コード例 #1
0
ファイル: sc4.c プロジェクト: glockwork/dfu
/*  store
 *
 *  Saves the contents of "primary" into a memory cell, either directly
 *  or indirectly (at the address given in the alternate register).
 */
SC_FUNC void store(value *lval)
{
  symbol *sym;

  sym=lval->sym;
  if (lval->ident==iARRAYCELL) {
    /* store at address in ALT */
    stgwrite("\tstor.i\n");
    code_idx+=opcodes(1);
  } else if (lval->ident==iARRAYCHAR) {
    /* store at address in ALT */
    stgwrite("\tstrb.i ");
    outval(sCHARBITS/8,TRUE,TRUE);   /* write one or two bytes */
    code_idx+=opcodes(1)+opargs(1);
  } else if (lval->ident==iREFERENCE) {
    assert(sym!=NULL);
    if (sym->vclass==sLOCAL)
      stgwrite("\tsref.s.pri ");
    else
      stgwrite("\tsref.pri ");
    outval(sym->addr,TRUE,TRUE);
    code_idx+=opcodes(1)+opargs(1);
  } else {
    assert(sym!=NULL);
    markusage(sym,uWRITTEN);
    if (sym->vclass==sLOCAL)
      stgwrite("\tstor.s.pri ");
    else
      stgwrite("\tstor.pri ");
    outval(sym->addr,TRUE,TRUE);
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
コード例 #2
0
ファイル: sc4.c プロジェクト: jte/pawn
SC_FUNC void fillarray(symbol *sym,cell size,cell value)
{
  ldconst(value,sPRI);  /* load value in PRI */

  assert(sym!=NULL);
  /* the symbol can be a local array, a global array, or an array
   * that is passed by reference.
   */
  if (sym->ident==iREFARRAY) {
    /* reference to an array; currently this is always a local variable */
    assert(sym->vclass==sLOCAL);        /* symbol must be stack relative */
    stgwrite("\tload.s.alt ");
  } else {
    /* a local or global array */
    if (sym->vclass==sLOCAL)
      stgwrite("\taddr.alt ");
    else
      stgwrite("\tconst.alt ");
  } /* if */
  outval(sym->addr,TRUE);
  markusage(sym,uWRITTEN);

  assert(size>0);
  stgwrite("\tfill ");
  outval(size,TRUE);

  code_idx+=opcodes(2)+opargs(2);
}
コード例 #3
0
ファイル: sc4.c プロジェクト: KyleSanderson/SourceMod
/*
 *  Call specified function
 */
SC_FUNC void ffcall(symbol *sym,const char *label,int numargs)
{
  char symname[2*sNAMEMAX+16];
  char aliasname[sNAMEMAX+1];
  int wasAlias = 0;

  assert(sym!=NULL);
  assert(sym->ident==iFUNCTN);
  if (sc_asmfile)
    funcdisplayname(symname,sym->name);
  if ((sym->usage & uNATIVE)!=0) {
    /* reserve a SYSREQ id if called for the first time */
    assert(label==NULL);
    stgwrite("\tsysreq.c ");
    if (sc_status==statWRITE && (sym->usage & uREAD)==0 && sym->addr>=0)
      sym->addr=ntv_funcid++;
    /* Look for an alias */
    if (lookup_alias(aliasname, sym->name)) {
      symbol *asym = findglb(aliasname, sGLOBAL);
      if (asym && asym->ident==iFUNCTN && ((sym->usage & uNATIVE) != 0)) {
        sym = asym;
        if (sc_status==statWRITE && (sym->usage & uREAD)==0 && sym->addr>=0) {
          sym->addr=ntv_funcid++;
          markusage(sym, uREAD);
        }
      }
    }
    outval(sym->addr,FALSE);
    if (sc_asmfile) {
      stgwrite("\t; ");
      stgwrite(symname);
    } /* if */
    stgwrite("\n"); /* write on a separate line, to mark a sequence point for the peephole optimizer */
    stgwrite("\tstack ");
    outval((numargs+1)*sizeof(cell), TRUE);
    code_idx+=opcodes(2)+opargs(2);
  } else {
    /* normal function */
    stgwrite("\tcall ");
    if (label!=NULL) {
      stgwrite("l.");
      stgwrite(label);
    } else {
      stgwrite(sym->name);
    } /* if */
    if (sc_asmfile
        && (label!=NULL || (!isalpha(sym->name[0]) && sym->name[0]!='_'  && sym->name[0]!=sc_ctrlchar)))
    {
      stgwrite("\t; ");
      stgwrite(symname);
    } /* if */
    stgwrite("\n");
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
コード例 #4
0
ファイル: sc4.cpp プロジェクト: sharivan/sourcepawn
// function value -> pri
void load_glbfn(symbol *sym)
{
  assert(sym->ident == iFUNCTN);
  assert(!(sym->usage & uNATIVE));
  stgwrite("\tldgfn.pri ");
  stgwrite(sym->name);
  stgwrite("\n");
  code_idx += opcodes(1) + opargs(1);

  if (sc_status != statSKIP)
    markusage(sym, uREAD);
}
コード例 #5
0
ファイル: sc4.cpp プロジェクト: sharivan/sourcepawn
/*  rvalue
 *
 *  Generate code to get the value of a symbol into "primary".
 */
void rvalue(value *lval)
{
  symbol *sym;

  sym=lval->sym;
  if (lval->ident==iARRAYCELL) {
    /* indirect fetch, address already in PRI */
    load_i();
  } else if (lval->ident==iARRAYCHAR) {
    /* indirect fetch of a character from a pack, address already in PRI */
    stgwrite("\tlodb.i ");
    outval(sCHARBITS/8,TRUE);   /* read one or two bytes */
    code_idx+=opcodes(1)+opargs(1);
  } else if (lval->ident==iREFERENCE) {
    /* indirect fetch, but address not yet in PRI */
    assert(sym!=NULL);
    assert(sym->vclass==sLOCAL);/* global references don't exist in Pawn */
    if (sym->vclass==sLOCAL)
      stgwrite("\tlref.s.pri ");
    else
      stgwrite("\tlref.pri ");
    outval(sym->addr,TRUE);
    markusage(sym,uREAD);
    code_idx+=opcodes(1)+opargs(1);
  } else if (lval->ident==iACCESSOR) {
    invoke_getter(lval->accessor);
    lval->ident=iEXPRESSION;
    lval->accessor=NULL;
  } else {
    /* direct or stack relative fetch */
    assert(sym!=NULL);
    if (sym->vclass==sLOCAL)
      stgwrite("\tload.s.pri ");
    else
      stgwrite("\tload.pri ");
    outval(sym->addr,TRUE);
    markusage(sym,uREAD);
    code_idx+=opcodes(1)+opargs(1);
  } /* if */
}
コード例 #6
0
ファイル: sc4.cpp プロジェクト: sharivan/sourcepawn
void invoke_getter(methodmap_method_t *method)
{
  if (!method->getter) {
    error(149, method->name);
    return;
  }

  // sysreq.n N 1
  // stack 8
  pushreg(sPRI);
  ffcall(method->getter, NULL, 1);

  if (sc_status != statSKIP)
    markusage(method->getter, uREAD);
}
コード例 #7
0
ファイル: sc4.cpp プロジェクト: sharivan/sourcepawn
void invoke_setter(methodmap_method_t *method, int save)
{
  if (!method->setter) {
    error(152, method->name);
    return;
  }

  if (save)
    pushreg(sPRI);
  pushreg(sPRI);
  pushreg(sALT);
  ffcall(method->setter, NULL, 2);
  if (save)
    popreg(sPRI);

  if (sc_status != statSKIP)
    markusage(method->setter, uREAD);
}
コード例 #8
0
ファイル: sc4.c プロジェクト: glockwork/dfu
/* Get the address of a symbol into the primary or alternate register (used
 * for arrays, and for passing arguments by reference).
 */
SC_FUNC void address(symbol *sym,regid reg)
{
  assert(sym!=NULL);
  assert(reg==sPRI || reg==sALT);
  /* the symbol can be a local array, a global array, or an array
   * that is passed by reference.
   */
  if (sym->ident==iREFARRAY || sym->ident==iREFERENCE) {
    /* reference to a variable or to an array; currently this is
     * always a local variable */
    switch (reg) {
    case sPRI:
      stgwrite("\tload.s.pri ");
      break;
    case sALT:
      stgwrite("\tload.s.alt ");
      break;
    } /* switch */
  } else {
    /* a local array or local variable */
    switch (reg) {
    case sPRI:
      if (sym->vclass==sLOCAL)
        stgwrite("\taddr.pri ");
      else
        stgwrite("\tconst.pri ");
      break;
    case sALT:
      if (sym->vclass==sLOCAL)
        stgwrite("\taddr.alt ");
      else
        stgwrite("\tconst.alt ");
      break;
    } /* switch */
  } /* if */
  outval(sym->addr,TRUE,TRUE);
  markusage(sym,uREAD);
  code_idx+=opcodes(1)+opargs(1);
}