static int mavis_parse_in(mavis_ctx * mcx, struct sym *sym) { while (1) { switch (sym->code) { case S_script: mavis_script_parse(mcx, sym); continue; case S_chroot: sym_get(sym); parse(sym, S_equal); mcx->ftp_chroot = parse_bool(sym); continue; case S_service: sym_get(sym); parse(sym, S_equal); strset(&mcx->service, sym->buf); sym_get(sym); continue; case S_eof: case S_closebra: return MAVIS_CONF_OK; default: parse_error_expect(sym, S_script, S_service, S_chroot, S_closebra, S_unknown); } } }
void op_asgngvarindex(void) { Var var, idx, expr, ret; int varno = frame.m->code[frame.pc++]; Error r; expr = pop(); idx = pop(); r = var_get_global(this, sym_get(frame.on, varno)->str, &var); if (r != E_NONE) { raise(r); } else if (!do_asgnindex(var, idx, expr, &ret)) { var = var_dup(var); var_assign_global(this, sym_get(frame.on, varno), ret); } }
/* * Step thru a symbol table list * * The cursor must be set by R_CURSOR, R_FIRST before using R_NEXT. * NULL is returned when no more items are available. */ int sym_seq(SYM sym, DBT *key, DBT *data, int flags) { SYM csym; switch(flags) { /* * A number of ways to do this: * specificly: sym_seq( .., "key,key") sets to Nth element of the 2nd * level symbol table * sym_seq(.., "key,key,") sets to the first element of the 3rd * level symbol table * * sym_seq(.., "key,key") where both must be complete keys, sets * cursor to the first element of the 3rd level symbol table; * if there is no 3rd level, return an error. */ case R_CURSOR: csym = (SYM) sym_get(sym, (char *)key->data); if (csym == NULL || csym->magic != SYM_MAGIC) { return(2); } sym->cursor = csym->sym; if (sym->cursor == NULL) return(1); key->data = sym->cursor->key; data->data = sym->cursor->data; return(0); case R_FIRST: sym->cursor = sym->sym; if (sym->cursor == NULL) return(1); key->data = sym->cursor->key; data->data = sym->cursor->data; return(0); case R_NEXT: if (sym->cursor == NULL) return(1); sym->cursor = sym->cursor->next; if (sym->cursor == NULL) return(1); key->data = sym->cursor->key; data->data = sym->cursor->data; return(0); case R_LAST: case R_PREV: default: return(-1); } }
void op_asgngvar(void) { Var v; int varno = frame.m->code[frame.pc++]; v = pop(); raise(var_assign_global(this, sym_get(frame.on, varno), v)); (void) pop(); }
void op_strpush(void) { Var s; int symno; symno = frame.m->code[frame.pc++]; s.type = STR; s.v.str = string_dup(sym_get(frame.on, symno)); push(s); }
static struct sym_info *get_or_create_sym(const char *symbol) { unsigned int pos; struct sym_info *sym = sym_get(symbol); if (sym == NULL) { pos = hash_string(symbol) % SYMTAB_SIZE; sym = sym_push(&symtab[pos], symbol, NULL, 0, NULL_EXPR, "", SYM_BIND_DEFAULT); sym->defined = 0; } return sym; }
/* Returns true (1) if the primative type was a 'null' type. */ extern int jw_is_null( void* st, const char* name ) { jthing_t* jtp; // thing that is referenced by the symtab if( st == NULL ) { return 0; } jtp = (jthing_t *) sym_get( st, name, 0 ); // get it or NULL if( ! jtp ) { return 0; } return jtp->prim_type == PT_NULL; }
void op_getsysvar(void) { int varno = frame.m->code[frame.pc++]; String *varname = sym_get(frame.on, varno); Var ret; Object *sys; if (!(sys = retrieve(sys_obj))) { raise(E_OBJNF); } else if (var_get_global(sys, varname->str, &ret) == E_VARNF) { raise(E_VARNF); } else { push(var_dup(ret)); } }
void op_getgvar(void) { Var ret; Error r; int varname; varname = frame.m->code[frame.pc++]; r = var_get_global(this, sym_get(frame.on, varname)->str, &ret); if (r != E_NONE) { raise(r); (void) pop(); /* what's this for? i forget */ } else { push (var_dup(ret)); } }
/* set a value now -- allows internal functions (like macro expansion or .gv) to set the value in the middle of processing rather than effective with the next command line read. 2011/08/21 */ extern void FMset_var( char *vname, char *buf ) { char *value = NULL; /* dup buffer to set name to */ char *ovalue = NULL; /* original value */ if( ! vname || ! *vname || !buf ) return; ovalue = sym_get( symtab, vname, 0 ); /* must free last */ if( ovalue ) free( ovalue ); value = strdup( buf ); sym_map( symtab, vname, 0, value ); /* add to symbol table */ TRACE(2, "set_var: name=%s val=(%s)\n", vname, buf ); }
/* Find the named array. Returns a pointer to the jthing that represents the array (type, size and pointer to actual array of jthings). */ static jthing_t* suss_array( void* st, const char* name ) { jthing_t* jtp; // thing that is referenced by the symtab if( st == NULL ) { return NULL; } if( (jtp = (jthing_t *) sym_get( st, name, 0 )) == NULL ) { return NULL; } if( jtp->jsmn_type != JSMN_ARRAY ) { return NULL; } return jtp; }
/* Look up name and return the blob (symtab). */ extern void* jw_blob( void* st, const char* name ) { jthing_t* jtp; // thing that is referenced by the symtab if( st == NULL ) { return NULL; } jtp = (jthing_t *) sym_get( st, name, 0 ); // get it or NULL if( ! jtp ) { return NULL; } if( jtp->jsmn_type != JSMN_OBJECT ) { return NULL; } return jtp->v.pv; }
/* Look up name and return the value. */ extern float jw_value( void* st, const char* name ) { jthing_t* jtp; // thing that is referenced by the symtab if( st == NULL ) { return 0; } jtp = (jthing_t *) sym_get( st, name, 0 ); // get it or NULL if( ! jtp ) { return 0; } if( jtp->jsmn_type != JSMN_PRIMITIVE ) { return 0; } return jtp->v.fv; }
/* Look up the name in the symtab and return the string (data). */ extern char* jw_string( void* st, const char* name ) { jthing_t* jtp; // thing that is referenced by the symtab if( st == NULL ) { return NULL; } jtp = (jthing_t *) sym_get( st, name, 0 ); // get it or NULL if( ! jtp ) { return NULL; } if( jtp->jsmn_type != JSMN_STRING ) { return NULL; } return (char *) jtp->v.pv; }
void op_message(void) { Var args; Var dest; String *msg; args = pop_args(count_args()); dest = pop(); if (dest.type != OBJ) { var_free(args); var_free(dest); frame.pc++; raise(E_INVIND); } else { msg = string_dup(sym_get(frame.on, frame.m->code[frame.pc])); frame.pc++; send_message_and_block(frame.this, dest.v.obj, msg, args.v.list, dest.v.obj); } }
static int mavis_parse_in(mavis_ctx * mcx, struct sym *sym) { while (1) { switch (sym->code) { case S_script: mavis_script_parse(mcx, sym); continue; case S_chroot: sym_get(sym); parse(sym, S_equal); mcx->ftp_chroot = parse_bool(sym); continue; case S_passwd: sym_get(sym); parse(sym, S_file); parse(sym, S_equal); strset(&mcx->passwordfile, sym->buf); sym_get(sym); continue; case S_ftpusers: sym_get(sym); parse(sym, S_file); parse(sym, S_equal); strset(&mcx->ftpuserspath, sym->buf); sym_get(sym); continue; case S_shells: sym_get(sym); parse(sym, S_file); parse(sym, S_equal); strset(&mcx->shellpath, sym->buf); sym_get(sym); continue; case S_sslusers: sym_get(sym); parse(sym, S_file); parse(sym, S_equal); strset(&mcx->ssluserspath, sym->buf); sym_get(sym); continue; case S_check: sym_get(sym); switch (sym->code) { case S_ftpusers: sym_get(sym); parse(sym, S_equal); mcx->honour_ftpusers = parse_bool(sym); break; case S_shells: sym_get(sym); parse(sym, S_equal); mcx->require_valid_shell = parse_bool(sym); break; case S_sslusers: sym_get(sym); parse(sym, S_equal); mcx->lookup_sslusers = parse_bool(sym); break; default: parse_error_expect(sym, S_ftpusers, S_shells, S_sslusers, S_unknown); } continue; case S_eof: case S_closebra: return MAVIS_CONF_OK; default: parse_error_expect(sym, S_script, S_userid, S_groupid, S_path, S_mode, S_closebra, S_unknown); } } }
/* Returns true (1) if the named field is in the blob; */ extern int jw_exists( void* st, const char* name ) { return sym_get( st, name, 0 ) != NULL; }
/* Returns true (1) if the named field is missing. */ extern int jw_missing( void* st, const char* name ) { return sym_get( st, name, 0 ) == NULL; }
/* *************************************************************************** * * Mnemonic: FMcmd * Abstract: This routine is responsible for dispatching the proper * routine to handle the command that was input by the user. * Commands are those tokins that begin with a period and are 2 * characters long. * Parms: buf - Pointer to the command. (.aa) * Returns: Nothing. * Date: 17 November 1988 * Author: E. Scott Daniels * * Modified: 1-1-89 - To support normal and definition lists * 4-30-98- To support user defined list item characters * 5-05-89- To support boxes * 6-10-89- To add .** as a comment line in the input file * 3 May 1991 - To support .ts (two sided) command * 4 May 1991 - To support page shifting * 5 May 1992 - To support postscript * 1 Oct 1992 - To support punctuation space command * 2 Nov 1992 - To add center command * 13 Nov 1992 - To free/malloc current font buffer * 3 Dec 1992 - To flush before setting font size or font * 6 Jun 1993 - To set y position for list item bullets higher * 21 Feb 1994 - To handle shift value in dlstack rather than old * left margin; correct multi column problem * and to call setstr for running strings * 21 Oct 2007 - Added index interface * 26 Jun 2013 - Prevents 0 text size from being set on .st command (happening * when .st &var and var not defined. * 03 Jan 2016 - Removed errant flush before FMll() and indent * calls. ************************************************************************** */ int FMcmd( char *buf ) { int cmd; /* command converted to integer for switch */ int i; /* temp integer */ struct li_blk *liptr; /* pointer to head to delete on a .el cmd */ char *ptr; /* dummy pointer to skip parameters */ int len; /* length of parameter returned */ int rc = 1; /* return code indicating command or not */ char wbuf[512]; char *tok; cmd = toupper( buf[1] ); i = toupper( buf[2] ); /* pick off and translate indiv characters */ cmd = (cmd << 8) + i; /* combine the characters */ switch( cmd ) { case C_ABORT: exit( 1 ); break; /* get out w/o end housekeeping */ case C_ASIS: flags2 |= F2_ASIS; break; case C_BEGDEFLST: FMbd( ); break; /* definition list */ case C_BEGLIST: FMbeglst( ); break; case C_BLOCKCTR: /* .bc {start|end} */ if( FMgetparm( &buf ) != 0 ) { FMflush( ); /* need to put out last one */ cenx1 = cur_col->lmar; cenx2 = cur_col->lmar + cur_col->width; /* defalult center */ if( *buf == 's' || *buf == 'S' ) flags2 |= F2_CENTER; else flags2 &= ~F2_CENTER; } break; case C_BOTY: /* .by [-]x[ip] if - (neg) then thats how far UP from bottom */ len = FMgetparm( &ptr ); boty = FMgetpts( ptr, len ); if( boty <= 0 ) boty += (11 * 72)-10; break; case C_BREAK: FMflush( ); break; case C_BOX: FMbox( ); break; case C_CAPTURE: FMcapture( ); break; case C_CCOL: FMccol( 0 ); break; case C_COLNOTES: FMcolnotes( ); break; case C_TABLECELL: FMcell( 1 ); break; case C_CENTER: FMcenter( ); break; case C_COLOUR: if( FMgetparm( &ptr ) > 0 ) { if( strcmp( ptr, "text" ) != 0 || FMgetparm( &ptr ) > 0 ) /* hfm compatable format since it allows bg, link colours to be set */ { if( textcolour ) free( textcolour ); FMsetcolour( ptr ); } } break; case C_COMMA: FMcomma( ); break; case C_COMMENT: FMskip( ); break; /* skip to real end of buffer not : */ case C_DEFHEADER: FMdefheader( ); break; case C_CDEFINE: FMcd( ); break; case C_EP: FMep( ); break; case C_CEJECT: PFMceject( ); /* eject column, flush page if in last column */ break; case C_CPAGE: FMcpage( ); break; case C_CSS: /* html cascading style sheet -- meaningless here */ FMignore( ); break; case C_DEFDELIM: /* define the variable definition delimiter */ if( FMgetparm( &ptr ) != 0 ) vardelim = ptr[0]; /* set the new pointer */ break; case C_DEFITEM: FMditem( ); break; case C_DEFVAR: FMdv( ); break; case C_DOUBLESPACE: flags = flags | DOUBLESPACE; break; case C_ELSE: FMelse( ); break; case C_ENDDEFLST: /* end definition list */ if( dlstackp >= 0 ) /* valid stack pointer? */ { flags2 &= ~F2_DIRIGHT; /* turn off the right justify flag for di's */ FMflush( ); i = dlstack[dlstackp].indent / PTWIDTH; /* calc line len shift */ lmar -= dlstack[dlstackp].indent; /* shift margin back to left */ linelen += dlstack[dlstackp].indent; /* reset line len */ dlstackp--; /* "pop" from the stack */ } break; case C_ENDIF: break; /* .fi encountered - ignore it */ case C_ENDLIST: /* end a list */ if( lilist != NULL ) /* if inside of a list */ { FMflush( ); /* clear anything that is there */ FMendlist( TRUE ); /* terminate the list and delete the block */ } break; case C_ENDTABLE: FMendtable( ); break; case C_EVAL: /* evaluate expression and push result */ if( FMgetparm( &buf ) > 0 ) /* get parameter entered */ AFIpushtoken( fptr->file, buf ); break; case C_FIGURE: FMfigure( ); break; case C_FLOATMAR: FMfloat_mar( ); break; case C_FORMAT: FMformat( ); break; case C_GETVALUE: FMgetval( ); break; case C_GREY: /* set grey scale for fills */ if( FMgetparm( &buf ) > 0 ) /* get parameter entered */ fillgrey = atoi( buf ); /* convert it to integer */ break; case C_HDMARG: FMindent( &hlmar ); break; case C_HLINE: FMcline( ); break; case C_HN: FMhn( ); break; case C_H1: FMheader( headers[0] ); break; case C_H2: FMheader( headers[1] ); break; case C_H3: FMheader( headers[2] ); break; case C_H4: FMheader( headers[3] ); break; case C_HYPHEN: if( FMgetparm( &buf ) > 0 ) /* get parameter entered */ { if( *(buf+1) == 'n' ) /* assume on */ flags3 |= F3_HYPHEN; else flags3 &= ~F3_HYPHEN; } else flags3 |= F3_HYPHEN; break; case C_IF: FMif( ); break; case C_IMBED: FMimbed( ); break; case C_INDENT: /* user indention of next line */ FMindent( &lmar ); /* indent the left margin value */ break; case C_INDEX: fmindex( ); break; case C_JUMP: FMjump( ); break; case C_JUSTIFY: FMsetjust( ); break; case C_LINESIZE: /* set line size for line command */ if( FMgetparm( &buf ) > 0 ) /* get the parameter */ { linesize = atoi( buf ); /* convert to integer */ if( linesize > 10 ) linesize = 2; /* dont allow them to be crazy */ } break; case C_LISTITEM: /* list item entered */ if( lilist != NULL && lilist->yindex < 60 ) { FMflush( ); /* output what we have so far */ if( cury + textspace + textsize > boty ) /* flush before marking */ PFMceject( ); lilist->ypos[lilist->yindex] = (cury + textsize); lilist->yindex++; /* point at next index */ } break; case C_LL: /* reset line length */ FMll( ); break; case C_LINE: FMline( ); break; case C_ONPAGEEJECT: FMoneject( ); break; /* on all eject commands */ case C_OUTLINE: /* use true charpath and fill instead of stroke */ if( FMgetparm( &buf ) > 0 ) /* get the parameter on | off */ { if( toupper( buf[1] ) == 'N' ) flags2 |= F2_TRUECHAR; /* turn on the flag */ else flags2 &= ~F2_TRUECHAR; /* turn off the flag */ } break; case C_NOFORMAT: /* turn formatting off */ FMflush( ); /* send last formatted line on its way */ flags = flags | NOFORMAT; /* turn no format flag on */ break; case C_PAGE: /* eject the page now */ FMflush( ); /* terminate the line in progress */ FMpflush(); /* and do the flush */ break; case C_PAGENUM: FMpgnum( ); break; case C_PAGEMAR: FMindent( &pageshift ); break; case C_POP: FMpop_state( ); break; case C_PUNSPACE: flags2 ^= F2_PUNSPACE; break; case C_PUSH: FMpush_state( ); break; case C_QUIT: if( !FMcolnotes_show( 1 ) ) /* push command(s) to show end notes which MUST contain another .qu! */ AFIclose( fptr->file ); /* if there wasn't end commands, then safe to close and exit now */ break; case C_RFOOT: FMsetstr( &rfoot, HEADFOOT_SIZE ); break; case C_RHEAD: FMsetstr( &rhead, HEADFOOT_SIZE ); break; case C_RESTARTTAB: TRACE( 1, ">>>++++ calling restart\n" ) FMrestart_table(); break; case C_SECTION: FMsection( ); break; case C_SETX: FMsetx( ); break; case C_SETY: FMsety( ); break; case C_SHOWV: if( (len = FMgetparm( &buf )) > 0 ) { if( strcmp( buf, "all" ) == 0 ) FMshowvars( ); else { if( (ptr = sym_get( symtab, buf, 0 )) ) fprintf( stderr, "(%s @ %ld) %s = (%s)\n", fptr->name, AFIstat( fptr->file, AFI_OPS, NULL), buf, ptr ); else fprintf( stderr, "(%s @ %ld) %s = UNDEFINED\n", fptr->name, AFIstat( fptr->file, AFI_OPS, NULL), buf ); } } break; case C_SINGLESPACE: /* turn off double space */ if( flags & DOUBLESPACE ) flags = flags & (255-DOUBLESPACE); break; case C_SKIP: if( cury == topy ) break; /* if not at top fall into space */ case C_SPACE: /* user wants blank lines */ FMspace( ); break; case C_SETFONT: /* set font for text (font name only parm) */ if( (len = FMgetparm( &ptr )) != 0 ) /* if a parameter was entered */ { *wbuf = 0; for( tok = ptr; *tok && (isalpha( *tok ) || *tok == '-'); tok++ ); if( *tok != 0 ) /* found non-alpha, assume closing . or ) or somesuch */ { strcpy( wbuf, tok ); *tok = 0; } TRACE( 2, "setfont old=%s new=%s\n", curfont, ptr ); free( curfont ); curfont = strdup( ptr ); FMfmt_add( ); /* add a format block to the list */ //if( *wbuf ) // AFIpushtoken( fptr->file, wbuf ); } else TRACE( 2, "setfont MISSING parameter!\n" ); break; case C_SETTXTSIZE: /* set text font size */ if( FMgetparm( &ptr ) ) /* must have parameter */ { if( (i = atoi( ptr )) > 5 ) /* if number is ok */ { TRACE( 2, "textsize set to: %d\n", i ); textsize = i; FMfmt_add( ); } else TRACE( 2, "textsize NOT set to: %d", i ); } else TRACE( 2, "textsize NOT, no parm" ); break; case C_SMASH: flags2 |= F2_SMASH; break; case C_TABLE: FMtable( ); break; case C_TABLEHEADER: FMth( ); break; case C_TABLEROW: FMtr( 0 ); break; case C_TMPFONT: FMtmpfont( ); break; case C_TMPTOP: FMtmpy( cmd ); break; case C_TOC: FMtc( ); break; case C_TOPGUT: // set the top gutter if( (len = FMgetparm( &ptr )) ) { i = FMgetpts( ptr, len ); if( i > 0 && i < topy ) { TRACE( 2, "top gutter set to: %d\n", i ); top_gutter = i; } else { TRACE( 2, "top gutter not set, not in range: %d topy=%d\n", i, topy ) } } else {
static int mavis_parse_in(mavis_ctx * mcx, struct sym *sym) { while (1) { switch (sym->code) { case S_script: mavis_script_parse(mcx, sym); continue; case S_userid: parse_userid(sym, &mcx->uid, &mcx->gid); continue; case S_groupid: parse_groupid(sym, &mcx->gid); continue; case S_home: sym_get(sym); parse(sym, S_equal); strset(&mcx->home, sym->buf); sym_get(sym); continue; case S_root: sym_get(sym); parse(sym, S_equal); strset(&mcx->root, sym->buf); sym_get(sym); continue; case S_upload: sym_get(sym); parse(sym, S_equal); strset(&mcx->incoming, sym->buf); sym_get(sym); continue; case S_eof: case S_closebra: { int bye = 0; if (!mcx->uid || !mcx->gid || !mcx->root) { struct passwd *pw; pw = getpwnam("ftp"); if (pw) { if (!mcx->uid) mcx->uid = pw->pw_uid; if (!mcx->gid) mcx->gid = pw->pw_gid; if (!mcx->root) mcx->root = Xstrdup(pw->pw_dir); } } if (!mcx->uid) { logmsg("%s: Fatal: anonymous ftp uid not set!", MAVIS_name); bye++; } if (!mcx->gid) { logmsg("%s: Fatal: anonymous ftp gid not set!", MAVIS_name); bye++; } if (!mcx->root) { logmsg("%s: Fatal: anonymous ftp root not set!", MAVIS_name); bye++; } if (bye) return -1; if (!mcx->home) mcx->home = Xstrdup("/"); return MAVIS_CONF_OK; } default: parse_error_expect(sym, S_script, S_userid, S_groupid, S_path, S_mode, S_closebra, S_unknown); } } }
static int mavis_parse_in(mavis_ctx * mcx, struct sym *sym) { u_int line; char *env_name; size_t len; struct stat st; while (1) { switch (sym->code) { case S_script: mavis_script_parse(mcx, sym); continue; case S_userid: parse_userid(sym, &mcx->uid, &mcx->gid); continue; case S_groupid: parse_groupid(sym, &mcx->gid); continue; case S_home: sym_get(sym); parse(sym, S_equal); strset(&mcx->home, sym->buf); sym_get(sym); continue; case S_childs: sym_get(sym); switch (sym->code) { case S_min: sym_get(sym); parse(sym, S_equal); mcx->child_min = parse_int(sym); continue; case S_max: sym_get(sym); parse(sym, S_equal); mcx->child_max = parse_int(sym); continue; default: parse_error_expect(sym, S_min, S_max, S_unknown); } case S_setenv: sym_get(sym); env_name = alloca(strlen(sym->buf) + 1); strcpy(env_name, sym->buf); sym_get(sym); parse(sym, S_equal); len = strlen(env_name) + strlen(sym->buf) + 2; mcx->env = Xrealloc(mcx->env, (mcx->envcount + 2) * sizeof(char *)); mcx->env[mcx->envcount] = Xcalloc(1, len); snprintf(mcx->env[mcx->envcount++], len, "%s=%s", env_name, sym->buf); mcx->env[mcx->envcount] = NULL; sym_get(sym); continue; case S_exec:{ char buf[MAX_INPUT_LINE_LEN]; sym_get(sym); parse(sym, S_equal); mcx->argv = calloc(1, sizeof(char *)); line = sym->line; ostypef(sym->buf, buf, sizeof(buf)); if (stat(buf, &st)) parse_error(sym, "%s: %s", buf, strerror(errno)); strset(&mcx->path, buf); sym_get(sym); while (sym->line == line) { mcx->argv = realloc(mcx->argv, (mcx->argc + 2) * sizeof(char *)); mcx->argv[mcx->argc] = strdup(sym->buf); mcx->argc++; mcx->argv[mcx->argc] = NULL; sym_get(sym); } if (!mcx->argv[0]) { mcx->argv = realloc(mcx->argv, 2 * sizeof(char *)); mcx->argv[0] = strdup(mcx->path); mcx->argv[1] = NULL; } continue; } case S_eof: case S_closebra: if (!mcx->argv) parse_error(sym, "Missing \"exec\" declaration."); return MAVIS_CONF_OK; default: parse_error_expect(sym, S_script, S_userid, S_groupid, S_home, S_childs, S_setenv, S_exec, S_closebra, S_unknown); } } }
void CodeGen_GPU_Host<CodeGen_CPU>::visit(const For *loop) { if (CodeGen_GPU_Dev::is_gpu_var(loop->name)) { // We're in the loop over innermost thread dimension debug(2) << "Kernel launch: " << loop->name << "\n"; ExtractBounds bounds; loop->accept(&bounds); debug(2) << "Kernel bounds: (" << bounds.num_threads[0] << ", " << bounds.num_threads[1] << ", " << bounds.num_threads[2] << ", " << bounds.num_threads[3] << ") threads, (" << bounds.num_blocks[0] << ", " << bounds.num_blocks[1] << ", " << bounds.num_blocks[2] << ", " << bounds.num_blocks[3] << ") blocks\n"; // compute a closure over the state passed into the kernel GPU_Host_Closure c(loop, loop->name); // compile the kernel string kernel_name = unique_name("kernel_" + loop->name, false); for (size_t i = 0; i < kernel_name.size(); i++) { if (!isalnum(kernel_name[i])) { kernel_name[i] = '_'; } } vector<GPU_Argument> closure_args = c.arguments(); for (size_t i = 0; i < closure_args.size(); i++) { if (closure_args[i].is_buffer && allocations.contains(closure_args[i].name)) { closure_args[i].size = allocations.get(closure_args[i].name).constant_bytes; } } cgdev->add_kernel(loop, kernel_name, closure_args); // get the actual name of the generated kernel for this loop kernel_name = cgdev->get_current_kernel_name(); debug(2) << "Compiled launch to kernel \"" << kernel_name << "\"\n"; Value *entry_name_str = builder->CreateGlobalStringPtr(kernel_name, "entry_name"); llvm::Type *target_size_t_type = (target.bits == 32) ? i32 : i64; // build the kernel arguments array llvm::PointerType *arg_t = i8->getPointerTo(); // void* int num_args = (int)closure_args.size(); // NULL-terminated list Value *gpu_args_arr = create_alloca_at_entry(ArrayType::get(arg_t, num_args+1), num_args+1, kernel_name + "_args"); // NULL-terminated list of size_t's Value *gpu_arg_sizes_arr = create_alloca_at_entry(ArrayType::get(target_size_t_type, num_args+1), num_args+1, kernel_name + "_arg_sizes"); for (int i = 0; i < num_args; i++) { // get the closure argument string name = closure_args[i].name; Value *val; if (closure_args[i].is_buffer) { // If it's a buffer, dereference the dev handle val = buffer_dev(sym_get(name + ".buffer")); } else { // Otherwise just look up the symbol val = sym_get(name); } // allocate stack space to mirror the closure element. It // might be in a register and we need a pointer to it for // the gpu args array. Value *ptr = builder->CreateAlloca(val->getType(), NULL, name+".stack"); // store the closure value into the stack space builder->CreateStore(val, ptr); // store a void* pointer to the argument into the gpu_args_arr Value *bits = builder->CreateBitCast(ptr, arg_t); builder->CreateStore(bits, builder->CreateConstGEP2_32(gpu_args_arr, 0, i)); // store the size of the argument int size_bits = (closure_args[i].is_buffer) ? target.bits : closure_args[i].type.bits; builder->CreateStore(ConstantInt::get(target_size_t_type, size_bits/8), builder->CreateConstGEP2_32(gpu_arg_sizes_arr, 0, i)); } // NULL-terminate the lists builder->CreateStore(ConstantPointerNull::get(arg_t), builder->CreateConstGEP2_32(gpu_args_arr, 0, num_args)); builder->CreateStore(ConstantInt::get(target_size_t_type, 0), builder->CreateConstGEP2_32(gpu_arg_sizes_arr, 0, num_args)); // TODO: only three dimensions can be passed to // cuLaunchKernel. How should we handle blkid[3]? internal_assert(is_one(bounds.num_threads[3]) && is_one(bounds.num_blocks[3])); Value *launch_args[] = { get_user_context(), builder->CreateLoad(get_module_state()), entry_name_str, codegen(bounds.num_blocks[0]), codegen(bounds.num_blocks[1]), codegen(bounds.num_blocks[2]), codegen(bounds.num_threads[0]), codegen(bounds.num_threads[1]), codegen(bounds.num_threads[2]), codegen(bounds.shared_mem_size), builder->CreateConstGEP2_32(gpu_arg_sizes_arr, 0, 0, "gpu_arg_sizes_ar_ref"), builder->CreateConstGEP2_32(gpu_args_arr, 0, 0, "gpu_args_arr_ref") }; llvm::Function *dev_run_fn = module->getFunction("halide_dev_run"); internal_assert(dev_run_fn) << "Could not find halide_dev_run in module\n"; Value *result = builder->CreateCall(dev_run_fn, launch_args); Value *did_succeed = builder->CreateICmpEQ(result, ConstantInt::get(i32, 0)); CodeGen_CPU::create_assertion(did_succeed, "Failure inside halide_dev_run"); } else { CodeGen_CPU::visit(loop); } }
/* parses input buffer for .dv command and defines the variable */ extern void FMdv( void ) { char *buf; /* parameter pointer */ char *value; /* pointer to current value - if prev defined */ char *ovalue; /* original value */ int len; /* length of the parameter */ char str[MAX_VAREXP+1]; /* pointer at the expansion string */ char name[128]; /* variable name */ int i; /* index vars */ int j; char tbuf[MAX_VARNAME+1]; /* tmp buffer to build new name in */ len = FMgetparm( &buf ); /* get the name */ if( len <= 0 ) return; /* no name entered then get out */ strncpy( name, buf, 127 ); name[128] = 0; /* ensure its marked */ ovalue = sym_get( symtab, name, 0 ); /* must free last incase referenced in the .dv string */ varbuf = NULL; /* not going to execute it so remove pointer */ i = j = 0; /* prep to load the new expansion information */ while( (len = FMgetparm( &buf )) > 0 ) /* get all parms on cmd line */ { if( trace > 1 ) fprintf( stderr, "dv adding tok: (%s)\n", buf ); for( i = 0; i < len && j < MAX_VAREXP; i++, j++ ) { if( buf[i] == '^' ) /* remove escape symbol */ switch( buf[i+1] ) /* only if next char is special*/ { case ':': case '`': case '[': case '^': i++; /* skip to escaped chr to copy */ break; default: /* not a special char - exit */ break; } /* end switch */ str[j] = buf[i]; /* copy in the next char */ } str[j++] = BLANK; /* seperate parms by a blank */ } j = j > 0 ? j - 1 : j; /* set to trash last blank if necessary */ str[j] = EOS; /* and do it! */ if( trace ) fprintf( stderr, "dv created var: %s = (%s)\n", name, str ); value = strdup( str ); sym_map( symtab, name, 0, value ); /* add to symbol table */ if( ovalue ) free( ovalue ); } /* FMdv */