/* - p_bre - BRE parser top level, anchoring and concatenation * Giving end1 as OUT essentially eliminates the end1/end2 check. * * This implementation is a bit of a kludge, in that a trailing $ is first * taken as an ordinary character and then revised to be an anchor. The * only undesirable side effect is that '$' gets included as a character * category in such cases. This is fairly harmless; not worth fixing. * The amount of lookahead needed to avoid this kludge is excessive. */ static void p_bre(struct parse *p, int end1, /* first terminating character */ int end2) /* second terminating character */ { sopno start = HERE(); int first = 1; /* first subexpression? */ int wasdollar = 0; if (EAT('^')) { EMIT(OBOL, 0); p->g->iflags |= USEBOL; p->g->nbol++; } while (MORE() && !SEETWO(end1, end2)) { wasdollar = p_simp_re(p, first); first = 0; } if (wasdollar) { /* oops, that was a trailing anchor */ DROP(1); EMIT(OEOL, 0); p->g->iflags |= USEEOL; p->g->neol++; } REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ }
static size_t join_paths(char *dst, size_t bufsize, const char *s1, const char *s2) { const char *list[2]; int i; char c; const char *p; char *q = dst; size_t n = 0; bool slash = false; list[0] = s1; list[1] = s2; for (i = 0; i < 2; i++) { p = list[i]; while ((c = *p++)) { if (c == '/') { if (!slash) EMIT(c); slash = true; } else { EMIT(c); slash = false; } } } if (bufsize) *q = '\0'; return n; }
/*************************************************************** ** Diagnostic routine that prints memory in table format. */ void DumpMemory( void *addr, int32 cnt) { int32 ln, cn, nlines; unsigned char *ptr, *cptr, c; nlines = (cnt + 15) / 16; ptr = (unsigned char *) addr; EMIT_CR; for (ln=0; ln<nlines; ln++) { MSG( ConvertNumberToText( (int32) ptr, 16, FALSE, 8 ) ); MSG(": "); cptr = ptr; for (cn=0; cn<16; cn++) { MSG( ConvertNumberToText( (int32) *cptr++, 16, FALSE, 2 ) ); EMIT(' '); } EMIT(' '); for (cn=0; cn<16; cn++) { c = *ptr++; if ((c < ' ') || (c > '}')) c = '.'; EMIT(c); } EMIT_CR; } }
static void cvt_d(fmt_code_info_t *info) { /* declare buf and p, initialize p */ char buf[200]; char *p = buf + sizeof(buf); #define EMIT(m) do { \ if(val == INT_MIN) \ m = INT_MAX + 1U; \ else if(val < 0) \ m = -val; \ else \ m = val; \ \ do \ *--p = (char)(m % 10 + '0'); \ while((m /= 10) > 0); \ \ if(val < 0) \ *--p = '-'; \ } while(0) if(info->flags['L']) { int64_t val = va_arg(*info->app, int64_t); int64_t m; EMIT(m); } else if(info->flags['l']) { long val = va_arg(*info->app, long); long m; EMIT(m); } else if(info->flags['h']) {
void BytecodeTranslatorVisitor::visitUnaryOpNode(UnaryOpNode* node) { onVisitNode(node); VISIT(node->operand()); switch (node->kind()) { case tNOT: { ensureTopType(VT_INT); /* if (!3.14) should fail */ Label L_True(bytecode()); Label L_End(bytecode()); EMIT(BC_ILOAD0); EMIT_BRANCH(BC_IFICMPE, L_True); EMIT(BC_ILOAD0); EMIT_BRANCH(BC_JA, L_End); EMIT_BIND(L_True); EMIT(BC_ILOAD1); EMIT_BIND(L_End); break; } case tSUB: ensureTopIsNumeric(); EMIT(TYPED(NEG)); break; default: ERROR("Unknown unary op"); } }
void BytecodeTranslatorVisitor::visitForNode(ForNode* node) { onVisitNode(node); const AstVar* i = node->var(); if (i->type() != VT_INT) ERROR("Non-iterable type in for loop"); const BinaryOpNode* expr = node->inExpr()->asBinaryOpNode(); if (expr == NULL || expr->kind() != tRANGE) ERROR("Invalid range in for loop"); CONTEXT(function(), locals(), node->body()->scope(), typeStack()); beforeProcessBlock(); bool needTempVar = !expr->right()->isIntLiteralNode(); AstVar* temp = NULL; if (needTempVar) { if (!scope()->declareVariable("<tempForEnd>", VT_INT)) ERROR("internal error: temp name is unavailable"); temp = scope()->lookupVariable("<tempForEnd>", false); } Label L_Begin(bytecode()); Label L_End(bytecode()); VISIT(expr->left()); EMIT_STORE(i); if (needTempVar) { VISIT(expr->right()); EMIT_STORE(temp); popType(VT_INT); } popType(VT_INT); EMIT_BIND(L_Begin); if (needTempVar) EMIT_LOAD(temp); else VISIT(expr->right()); EMIT_LOAD(i); EMIT_BRANCH(BC_IFICMPG, L_End); processBlockNode(node->body()); afterProcessBlock(); /* i += 1 */ EMIT_LOAD(i); EMIT(BC_ILOAD1); EMIT(BC_IADD); EMIT_STORE(i); EMIT_BRANCH(BC_JA, L_Begin); EMIT_BIND(L_End); pushType(VT_VOID); }
bool emit_quoted_scalar(const node *each) { EMIT("'"); if(!emit_raw_scalar(each)) { log_error("shell", "uh oh! couldn't emit quoted scalar"); return false; } EMIT("'"); return true; }
static bool emit_json_quoted_scalar(const Scalar *each) { EMIT("\""); if(!emit_json_raw_scalar(each)) { log_error(component, "uh oh! couldn't emit quoted scalar"); return false; } EMIT("\""); return true; }
/* * C-style name quoting. * * (1) if sb and fp are both NULL, inspect the input name and counts the * number of bytes that are needed to hold c_style quoted version of name, * counting the double quotes around it but not terminating NUL, and * returns it. * However, if name does not need c_style quoting, it returns 0. * * (2) if sb or fp are not NULL, it emits the c_style quoted version * of name, enclosed with double quotes if asked and needed only. * Return value is the same as in (1). */ static size_t quote_c_style_counted(const char *name, ssize_t maxlen, struct strbuf *sb, FILE *fp, int no_dq) { #undef EMIT #define EMIT(c) \ do { \ if (sb) strbuf_addch(sb, (c)); \ if (fp) fputc((c), fp); \ count++; \ } while (0) #define EMITBUF(s, l) \ do { \ if (sb) strbuf_add(sb, (s), (l)); \ if (fp) fwrite((s), (l), 1, fp); \ count += (l); \ } while (0) size_t len, count = 0; const char *p = name; for (;;) { int ch; len = next_quote_pos(p, maxlen); if (len == maxlen || (maxlen < 0 && !p[len])) break; if (!no_dq && p == name) EMIT('"'); EMITBUF(p, len); EMIT('\\'); p += len; ch = (unsigned char)*p++; if (maxlen >= 0) maxlen -= len + 1; if (sq_lookup[ch] >= ' ') { EMIT(sq_lookup[ch]); } else { EMIT(((ch >> 6) & 03) + '0'); EMIT(((ch >> 3) & 07) + '0'); EMIT(((ch >> 0) & 07) + '0'); } } EMITBUF(p, len); if (p == name) /* no ending quote needed */ return 0; if (!no_dq) EMIT('"'); return count; }
void BytecodeTranslatorVisitor::visitStringLiteralNode(StringLiteralNode * node) { onVisitNode(node); if (node->literal().empty()) EMIT(BC_SLOAD0); else { EMIT(BC_SLOAD); EMIT_ID(code()->makeStringConstant(node->literal())); } pushType(VT_STRING); }
void BytecodeTranslatorVisitor::processNumericOperation(TokenKind op) { castTopsToCommonType(); switch (op) { case tADD: EMIT(TYPED(ADD)); break; case tSUB: EMIT(TYPED(SUB)); break; case tMUL: EMIT(TYPED(MUL)); break; default : EMIT(TYPED(DIV)); break; } popType(); ensureTopIsNumeric(); }
static bool emit_json_mapping_item(Node *key, Node *value, void *context) { log_trace(component, "emitting mapping item"); size_t *count = (size_t *)context; if(0 != (*count)++) { EMIT(","); } if(!emit_json_quoted_scalar(scalar(key))) { return false; } EMIT(":"); return emit_json_node(value, NULL); }
void BytecodeTranslatorVisitor::visitIntLiteralNode(IntLiteralNode* node) { onVisitNode(node); switch (node->literal()) { case -1: EMIT(BC_ILOADM1); break; case 0: EMIT(BC_ILOAD0); break; case 1: EMIT(BC_ILOAD1); break; default: EMIT(BC_ILOAD); EMIT_INT(node->literal()); break; } pushType(VT_INT); }
/* ( ... --- ... , print stack ) */ void ffDotS( void ) { cell *sp; int32 i, Depth; MSG("Stack<"); MSG( ConvertNumberToText( gVarBase, 10, TRUE, 1 ) ); /* Print base in decimal. */ MSG("> "); Depth = gCurrentTask->td_StackBase - gCurrentTask->td_StackPtr; sp = gCurrentTask->td_StackBase; if( Depth < 0 ) { MSG("UNDERFLOW!"); } else { for( i=0; i<Depth; i++ ) { /* Print as unsigned if not base 10. */ MSG( ConvertNumberToText( *(--sp), gVarBase, (gVarBase == 10), 1 ) ); EMIT(' '); } } MSG("\n"); }
/* - doinsert - insert a sop into the strip */ static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos) { sopno sn; sop s; int i; /* avoid making error situations worse */ if (p->error != 0) return; sn = HERE(); EMIT(op, opnd); /* do checks, ensure space */ assert(HERE() == sn+1); s = p->strip[sn]; /* adjust paren pointers */ assert(pos > 0); for (i = 1; i < NPAREN; i++) { if (p->pbegin[i] >= pos) { p->pbegin[i]++; } if (p->pend[i] >= pos) { p->pend[i]++; } } memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], (HERE()-pos-1)*sizeof(sop)); p->strip[pos] = s; }
void Recorder::onRecord(XnUInt32 nodeId, XnCodecBase* pCodec, const OniFrame* pFrame, XnUInt32 frameId, XnUInt64 timestamp) { if (0 == nodeId || NULL == pFrame) { return; } FIND_ATTACHED_STREAM_INFO(nodeId) if (!pInfo) return; Memento undoPoint(this); if (NULL != pCodec) { XnUInt32 bufferSize_bytes32 = pFrame->dataSize * 2 + pCodec->GetOverheadSize(); XnUInt8* buffer = XN_NEW_ARR(XnUInt8, bufferSize_bytes32); XnStatus status = pCodec->Compress(reinterpret_cast<const XnUChar*>(pFrame->data), pFrame->dataSize, buffer, &bufferSize_bytes32); XnSizeT bufferSize_bytes = bufferSize_bytes32; if (XN_STATUS_OK == status) { EMIT(RECORD_NEW_DATA( nodeId, pInfo->lastNewDataRecordPosition, timestamp, frameId, buffer, bufferSize_bytes)) } XN_DELETE_ARR(buffer); }
void irc_status_busy(connection_t *c, int on, char *msg) { c->status &= ~STATUS_MASK; if (on) { c->status |= STATUS_BUSY; if (msg != NULL) { IRC(c)->away = a_strdup(c->area, msg); PDEBUG("vado in away: %s", IRC(c)->away); } } else { c->status |= STATUS_AVAILABLE; if (IRC(c)->away != NULL) { a_free(c->area, IRC(c)->away); IRC(c)->away = NULL; } } EMIT(c, "send status"); IRC_SEND_SRVMODE(c, c->nick, c->nick, (on) ? "+a" : "-a"); }
void BytecodeTranslatorVisitor::visitBinaryOpNode(BinaryOpNode * node) { onVisitNode(node); TokenKind op = node->kind(); if (op == tOR || op == tAND) { processLazyLogic(node); return; } VISIT(node->right()); ensureTopIsNumeric(); VISIT(node->left()); ensureTopIsNumeric(); if (tEQ <= op && op <= tLE) processComparison(node->kind()); else if (tADD <= op && op <= tDIV) processNumericOperation(node->kind()); else if (op == tMOD || op == tAXOR || op == tAOR || op == tAAND) { popType(VT_INT); ensureTopType(VT_INT); EMIT(op == tAXOR ? BC_IAXOR : op == tMOD ? BC_IMOD : op == tAOR ? BC_IAOR : BC_IAAND); } else ERROR("Unknown binary op"); }
void BytecodeTranslatorVisitor::visitDoubleLiteralNode(DoubleLiteralNode* node) { onVisitNode(node); const double value = node->literal(); if (doubleEquals(value, -1.0)) EMIT(BC_DLOADM1); else if (doubleEquals(value, 0.0)) EMIT(BC_DLOAD0); else if (doubleEquals(value, 1.0)) EMIT(BC_DLOAD1); else { EMIT(BC_DLOAD); EMIT_DOUBLE(value); } pushType(VT_DOUBLE); }
void BytecodeTranslatorVisitor::castTopsToCommonType() { VarType hi = popType(); VarType lo = popType(); if (hi != lo) { if (hi == VT_DOUBLE) { EMIT(BC_SWAP); EMIT(BC_I2D); EMIT(BC_SWAP); } else { EMIT(BC_I2D); } hi = VT_DOUBLE; } pushType(hi); pushType(hi); }
void TestSigSlot() { puts("connecting slot..."); CONNECT(TestSignal, slot); puts("emitting signal..."); EMIT(TestSignal, 30); puts("\ndone"); }
void Recorder::onStart(XnUInt32 nodeId) { if (0 == nodeId) { return; } Memento undoPoint(this); EMIT(RECORD_NODE_STATE_READY( nodeId )) EMIT(RECORD_NODE_DATA_BEGIN( nodeId, /* framesCount = */ XN_MAX_UINT32, /* maxTimeStamp = */ XN_MAX_UINT64 )) undoPoint.Release(); }
void BytecodeTranslatorVisitor::visitPrintNode(PrintNode * node) { onVisitNode(node); for (uint32_t i = 0; i < node->operands(); ++i) { VISIT(node->operandAt(i)); switch (topType()) { case VT_INT: EMIT(BC_IPRINT); break; case VT_DOUBLE: EMIT(BC_DPRINT); break; case VT_STRING: EMIT(BC_SPRINT); break; default: ERROR("Unprintable parameter"); } popType(); } pushType(VT_VOID); }
void MessageAdder::emitSignals() { kulloAssert(addMessageHasBeenRun_); // sender must be available when message is added, so senderAdded must be // emitted before messageAdded EMIT(events.senderAdded, convId_, msgId_); EMIT(events.messageAdded, convId_, msgId_); if (newConversation_) { EMIT(events.conversationAdded, convId_); } else { EMIT(events.conversationModified, convId_); } }
void Recorder::onDetach(XnUInt32 nodeId) { if (nodeId == 0) { return; } FIND_ATTACHED_STREAM_INFO(nodeId) if (!pInfo) return; Memento undoPoint(this); EMIT(RECORD_NODE_REMOVED( nodeId, pInfo->nodeAddedRecordPosition )) undoPoint.Release(); undoPoint.Reuse(); XnUInt64 nSeekTablePos = undoPoint.GetPosition(); // write the seek table EMIT(RECORD_SEEK_TABLE( nodeId, pInfo->frameId, pInfo->dataIndex )) undoPoint.Release(); undoPoint.Reuse(); // Seek to position of node added record undoPoint.SetPosition(pInfo->nodeAddedRecordPosition); // re-write this record, this time with seek data EMIT(RECORD_NODE_ADDED( pInfo->nodeType, nodeId, pInfo->codecId, /* numberOfFrames = */ pInfo->frameId, /* minTimeStamp = */ XN_UINT64_C(0), /* maxTimeStamp = */ pInfo->lastOutputTimestamp, /* seekTablePosition = */ nSeekTablePos )) undoPoint.Undo(); }
static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx) { int i; const struct sock_filter *filter = fp->insns; if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) { /* Make stackframe */ if (ctx->seen & SEEN_DATAREF) { /* If we call any helpers (for loads), save LR */ EMIT(PPC_INST_MFLR | __PPC_RT(R0)); PPC_BPF_STL(0, 1, PPC_LR_STKOFF); /* Back up non-volatile regs. */ PPC_BPF_STL(r_D, 1, -(REG_SZ*(32-r_D))); PPC_BPF_STL(r_HL, 1, -(REG_SZ*(32-r_HL))); } if (ctx->seen & SEEN_MEM) { /* * Conditionally save regs r15-r31 as some will be used * for M[] data. */ for (i = r_M; i < (r_M+16); i++) { if (ctx->seen & (1 << (i-r_M))) PPC_BPF_STL(i, 1, -(REG_SZ*(32-i))); } } PPC_BPF_STLU(1, 1, -BPF_PPC_STACKFRAME); } if (ctx->seen & SEEN_DATAREF) { /* * If this filter needs to access skb data, * prepare r_D and r_HL: * r_HL = skb->len - skb->data_len * r_D = skb->data */ PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff, data_len)); PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len)); PPC_SUB(r_HL, r_HL, r_scratch1); PPC_LL_OFFS(r_D, r_skb, offsetof(struct sk_buff, data)); } if (ctx->seen & SEEN_XREG) { /* * TODO: Could also detect whether first instr. sets X and * avoid this (as below, with A). */ PPC_LI(r_X, 0); } /* make sure we dont leak kernel information to user */ if (bpf_needs_clear_a(&filter[0])) PPC_LI(r_A, 0); }
void emit_common_delete_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qst) { // assumes pass is greater than 1, ie that all identifiers are defined in the scope id_info_t *id = scope_find(scope, qst); assert(id != NULL); // TODO can this ever fail? // call the emit backend with the correct code if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) { EMIT(delete_name, qst); } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) { EMIT(delete_global, qst); } else if (id->kind == ID_INFO_KIND_LOCAL) { EMIT(delete_fast, qst, id->local_num); } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) { EMIT(delete_deref, qst, id->local_num); } else { assert(0); } }
static bool emit_json_sequence_item(Node *each, void *context) { log_trace(component, "emitting sequence item"); size_t *count = (size_t *)context; if(0 != (*count)++) { EMIT(","); } return emit_json_node(each, NULL); }
void BytecodeTranslatorVisitor::visitCallNode(CallNode* node) { onVisitNode(node); AstFunction* f = scope()->lookupFunction(node->name()); if (!f) ERROR("Unknown function " + f->name()); checkSignature(node, f); for (uint16_t i = 0; i < node->parametersNumber(); i++) visitTyped(node->parameterAt(i), f->parameterType(i)); if (isNative(f)) EMIT(BC_CALLNATIVE); else EMIT(BC_CALL); EMIT_ID(getFunctionId(f)); pushType(f->returnType()); }
void BytecodeTranslatorVisitor::loadStoreLocal(uint16_t id, VarType type, bool load) { static Instruction tableLocal[2 * VAR_TYPES_NUMBER] = {BC_INVALID, BC_INVALID, BC_LOADDVAR, BC_LOADIVAR, BC_LOADSVAR, BC_INVALID, BC_INVALID, BC_STOREDVAR, BC_STOREIVAR, BC_STORESVAR}; static Instruction tableRegister[2 * VAR_TYPES_NUMBER] = {BC_INVALID, BC_INVALID, BC_LOADDVAR0, BC_LOADIVAR0, BC_LOADSVAR0, BC_INVALID, BC_INVALID, BC_STOREDVAR0, BC_STOREIVAR0, BC_STORESVAR0}; uint16_t offset = type + (load ? 0 : VAR_TYPES_NUMBER); assert(tableLocal[offset] != BC_INVALID); if (id < VAR_REGISTERS_NUMBER) EMIT(tableRegister[offset] + id); else { EMIT(tableLocal[offset]); EMIT_ID(id); } }