示例#1
0
static PTREE genVfunCall(       // DIRECTLY GENERATE VFUN CALL
    target_offset_t vf_offset,  // - offset to VF table ptr
    PTREE node,                 // - original "this" expression
    target_offset_t vf_index,   // - index into VF table
    SYMBOL sym )                // - symbol to access
{
    TYPE vfptr_type;            // - type[ ptr to VF table ]
    TYPE vfn_type;              // - type[ ptr to VF ]

    node = NodeBinary( CO_DOT, node, NodeOffset( vf_offset ) );
    vfptr_type = MakeVFTableFieldType( TRUE );
    node->type = vfptr_type;
    node->flags |= PTF_LVALUE;
    node = PtdExprConst( node );
    node = NodeRvalue( node );
    vfn_type = TypePointedAtModified( vfptr_type );
    node = NodeBinary( CO_DOT
                     , node
                     , NodeOffset( vf_index * CgMemorySize( vfn_type ) ) );
    node->type = vfn_type;
    node->flags |= PTF_LVALUE;
    node = NodeRvalue( node );
    node->type = sym->sym_type;
    return node;
}
示例#2
0
PTREE NodeConvertVirtualPtr(    // EXECUTE A VIRTUAL BASE CAST
    PTREE expr,                 // - expr to cast
    TYPE final_type,            // - final type after cast
    target_offset_t vb_offset,  // - offset of vbptr
    vindex vb_index )           // - index in vbtable
{
    PTREE offset;
    TYPE vbptr_type;
    TYPE adjust_type;
    PTREE dup;

    vbptr_type = MakeVBTableFieldType( true );
    offset = NodeOffset( vb_offset );
    expr = NodeBinary( CO_DOT, expr, offset );
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    expr->type = vbptr_type;
    dup = NodeDupExpr( &expr );
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    expr = NodeFetch( expr );
    expr->type = vbptr_type;
    expr->flags &= ~ PTF_LVALUE;
    expr->flags |= PTF_PTR_NONZERO;
    adjust_type = TypePointedAtModified( vbptr_type );
    offset = NodeOffset( vb_index * CgMemorySize( adjust_type ) );
    expr = NodeBinary( CO_DOT, expr, offset );
    expr->type = adjust_type;
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    expr = NodeFetch( expr );
    expr->type = adjust_type;
    expr->flags |= PTF_PTR_NONZERO;
    expr = NodeBinary( CO_DOT, dup, expr );
    expr->type = final_type;
    expr->flags |= PTF_LVALUE | PTF_PTR_NONZERO;
    return( expr );
}
示例#3
0
PTREE MakeDeleteCall(   // MAKE A CALL TO 'OPERATOR DELETE'
    SYMBOL del_sym,     // - symbol for 'op del'
    PTREE ptr,          // - parm 1 for delete
    TYPE class_parm )   // - if non-NULL, use size as second parm
{
    PTREE size_arg;     // - size argument for call
    PTREE args;         // - arguments for call
    PTREE expr;         // - final expression
    arg_list *del_args; // - op del arguments

    del_args = SymFuncArgList( del_sym );
    args = NULL;
    if( class_parm != NULL ) {
        size_arg = NodeOffset( class_parm->u.c.info->size );
        size_arg = NodeConvert( del_args->type_list[1], size_arg );
        args = NodeArgument( args, size_arg );
    }
    ptr = NodeConvert( del_args->type_list[0], ptr );
    args = NodeArgument( args, ptr );
    expr = NodeMakeCall( del_sym, GetBasicType( TYP_VOID ), NULL );
    expr = CallArgsArrange( del_sym->sym_type
                          , expr
                          , args
                          , NULL
                          , NULL
                          , NULL );
    return expr;
}
mozInlineSpellWordUtil::NodeOffset
mozInlineSpellWordUtil::MapSoftTextOffsetToDOMPosition(PRInt32 aSoftTextOffset,
                                                       DOMMapHint aHint)
{
  NS_ASSERTION(mSoftTextValid, "Soft text must be valid if we're to map out of it");
  if (!mSoftTextValid)
    return NodeOffset(nsnull, -1);
  
  // The invariant is that the range start..end includes the last mapping,
  // if any, such that mSoftTextOffset <= aSoftTextOffset
  PRInt32 start = 0;
  PRInt32 end = mSoftTextDOMMapping.Length();
  while (end - start >= 2) {
    PRInt32 mid = (start + end)/2;
    const DOMTextMapping& map = mSoftTextDOMMapping[mid];
    if (map.mSoftTextOffset > aSoftTextOffset) {
      end = mid;
    } else {
      start = mid;
    }
  }
  
  if (start >= end)
    return NodeOffset(nsnull, -1);

  // 'start' is now the last mapping, if any, such that
  // mSoftTextOffset <= aSoftTextOffset.
  // If we're doing HINT_END, then we may want to return the end of the
  // the previous mapping instead of the start of this mapping
  if (aHint == HINT_END && start > 0) {
    const DOMTextMapping& map = mSoftTextDOMMapping[start - 1];
    if (map.mSoftTextOffset + map.mLength == aSoftTextOffset)
      return NodeOffset(map.mNodeOffset.mNode, map.mNodeOffset.mOffset + map.mLength);
  }
  
  // We allow ourselves to return the end of this mapping even if we're
  // doing HINT_START. This will only happen if there is no mapping which this
  // point is the start of. I'm not 100% sure this is OK...
  const DOMTextMapping& map = mSoftTextDOMMapping[start];
  PRInt32 offset = aSoftTextOffset - map.mSoftTextOffset;
  if (offset >= 0 && offset <= map.mLength)
    return NodeOffset(map.mNodeOffset.mNode, map.mNodeOffset.mOffset + offset);
    
  return NodeOffset(nsnull, -1);
}
示例#5
0
static PTREE makeTrueFalse( PTREE expr, PTREE op, int value )
{
    PTREE node;

    if(( op->flags & PTF_SIDE_EFF ) != 0 ) {
        return( expr );
    }
    if( anachronismFound( op ) ) {
        return( expr );
    }
    node = NodeOffset( value );
    node = NodeSetBooleanType( node );
    node = PTreeCopySrcLocation( node, expr );
    NodeFreeDupedExpr( expr );
    return( node );
}
nsresult
mozInlineSpellWordUtil::SetEnd(nsIDOMNode* aEndNode, PRInt32 aEndOffset)
{
  NS_PRECONDITION(aEndNode, "Null end node?");

  NS_ASSERTION(mRootNode, "Not initialized");

  InvalidateWords();

  if (!IsTextNode(aEndNode)) {
    // End at the start of the first text node after aEndNode/aEndOffset.
    aEndNode = FindNextTextNode(aEndNode, aEndOffset, mRootNode);
    aEndOffset = 0;
  }
  mSoftEnd = NodeOffset(aEndNode, aEndOffset);
  return NS_OK;
}
示例#7
0
static void adjust_by_delta(    // COMPUTE DELTA ADJUSTMENT
    PTREE *a_expr,              // - addr( ptr to be converted )
    TYPE base,                  // - base type
    unsigned delta,             // - adjustment
    bool positive )             // - true ==> use positive value
{
    PTREE offset;               // - node containing delta

    if( delta == 0 ) {
        *a_expr = NodeConvert( base, *a_expr );
    } else {
        offset = NodeOffset( delta );
        if( ! positive ) {
            offset->u.int_constant = - delta;
        }
        *a_expr = adjust_base_ptr( *a_expr, offset, base );
    }
}
nsresult
mozInlineSpellWordUtil::GetRangeForWord(nsIDOMNode* aWordNode,
                                        PRInt32 aWordOffset,
                                        nsIDOMRange** aRange)
{
  // Set our soft end and start
  NodeOffset pt = NodeOffset(aWordNode, aWordOffset);
  
  InvalidateWords();
  mSoftBegin = mSoftEnd = pt;
  EnsureWords();
  
  PRInt32 offset = MapDOMPositionToSoftTextOffset(pt);
  if (offset < 0)
    return MakeRange(pt, pt, aRange);
  PRInt32 wordIndex = FindRealWordContaining(offset, HINT_BEGIN, PR_FALSE);
  if (wordIndex < 0)
    return MakeRange(pt, pt, aRange);
  return MakeRangeForWord(mRealWords[wordIndex], aRange);
}
nsresult
mozInlineSpellWordUtil::SetPosition(nsIDOMNode* aNode, PRInt32 aOffset)
{
  InvalidateWords();

  if (!IsTextNode(aNode)) {
    // Start at the start of the first text node after aNode/aOffset.
    aNode = FindNextTextNode(aNode, aOffset, mRootNode);
    aOffset = 0;
  }
  mSoftBegin = NodeOffset(aNode, aOffset);

  EnsureWords();
  
  PRInt32 textOffset = MapDOMPositionToSoftTextOffset(mSoftBegin);
  if (textOffset < 0)
    return NS_OK;
  mNextWordIndex = FindRealWordContaining(textOffset, HINT_END, PR_TRUE);
  return NS_OK;
}
示例#10
0
static PTREE DynamicCastVoid           // DYNAMIC CAST CODE: VOID *
    ( CONVCTL* ctl )            // - conversion information
{
    PTREE expr;                 // - cast expression
    PTREE from;                 // - type being case from
    TOKEN_LOCN locn;            // - cast location
    CLASSINFO *info;            // - source (or base class of source) class info

    expr = ctl->expr;
    expr = PTreeExtractLocn( expr, &locn );
    expr = NodePruneLeftTop( expr );
    expr->locn = locn;
    from = NodeTypeid( ctl->src.pted );
    info = GetWithinOffsetOfVFPtr( ctl->src.pted, &expr );
    expr = NodeArguments( from
                        , NodeOffset( info->vf_offset )
                        , expr
                        , NULL );
    expr = RunTimeCall( expr, ctl->tgt.orig , RTF_DYN_CAST_VOID );
    return( expr );
}
示例#11
0
PTREE DynamicCast               // DYNAMIC CAST CODE
    ( CONVCTL* ctl )            // - conversion information
{
    PTREE expr;                 // - cast expression
    TOKEN_LOCN locn;            // - cast location
    PTREE from;                 // - type being cast from
    PTREE to;                   // - type being cast to
    CLASSINFO *info;            // - source (or base class of source) class info

    if( ctl->tgt.pted->id == TYP_VOID ) {
        return( DynamicCastVoid( ctl ) );
    } else {
        expr = ctl->expr;
        expr = PTreeExtractLocn( expr, &locn );
        expr = NodePruneLeftTop( expr );
        expr->locn = locn;
        from = NodeTypeid( ctl->src.pted );
        to = NodeTypeid( ctl->tgt.pted );
        info = GetWithinOffsetOfVFPtr( ctl->src.pted, &expr );
        expr = NodeArguments( to
                            , from
                            , NodeOffset( info->vf_offset )
                            , expr
                            , NULL );
        DbgAssert( ctl->src.reference == ctl->tgt.reference );
        if( ctl->src.reference && ctl->tgt.reference ) {
            // ref => ref
            expr = RunTimeCall( expr, ctl->tgt.orig, RTF_DYN_CAST_REF );
        } else {
            // ptr => ptr
            DbgAssert( !ctl->src.reference && !ctl->tgt.reference );
            expr = RunTimeCall( expr, ctl->tgt.orig , RTF_DYN_CAST_PTR );
        }
    }
    return( expr );
}
void
mozInlineSpellWordUtil::BuildSoftText()
{
  // First we have to work backwards from mSoftStart to find a text node
  // containing a DOM word separator, a non-inline-element
  // boundary, or the hard start node. That's where we'll start building the
  // soft string from.
  nsIDOMNode* node = mSoftBegin.mNode;
  PRInt32 firstOffsetInNode = 0;
  PRInt32 checkBeforeOffset = mSoftBegin.mOffset;
  while (node) {
    if (ContainsDOMWordSeparator(node, checkBeforeOffset, &firstOffsetInNode))
      break;
    checkBeforeOffset = PR_INT32_MAX;
    if (IsBreakElement(mCSSView, node)) {
      // Since FindPrevNode follows tree *preorder*, we're about to traverse
      // up out of 'node'. Since node induces breaks (e.g., it's a block),
      // don't bother trying to look outside it, just stop now.
      break;
    }
    node = FindPrevNode(node, mRootNode);
  }

  // Now build up the string moving forward through the DOM until we reach
  // the soft end and *then* see a DOM word separator, a non-inline-element
  // boundary, or the hard end node.
  mSoftText.Truncate();
  mSoftTextDOMMapping.Clear();
  PRBool seenSoftEnd = PR_FALSE;
  // Leave this outside the loop so large heap string allocations can be reused
  // across iterations
  nsAutoString str;
  while (node) {
    if (node == mSoftEnd.mNode) {
      seenSoftEnd = PR_TRUE;
    }

    PRBool exit = PR_FALSE;
    if (IsTextNode(node)) {
      GetNodeText(node, str);
      PRInt32 lastOffsetInNode = str.Length();

      if (seenSoftEnd) {
        // check whether we can stop after this
        for (PRInt32 i = node == mSoftEnd.mNode ? mSoftEnd.mOffset : 0;
             i < PRInt32(str.Length()); ++i) {
          if (IsDOMWordSeparator(str.CharAt(i))) {
            exit = PR_TRUE;
            // stop at the first separator after the soft end point
            lastOffsetInNode = i;
            break;
          }
        }
      }
      
      if (firstOffsetInNode < lastOffsetInNode) {
        PRInt32 len = lastOffsetInNode - firstOffsetInNode;
        mSoftTextDOMMapping.AppendElement(
          DOMTextMapping(NodeOffset(node, firstOffsetInNode), mSoftText.Length(), len));
        mSoftText.Append(Substring(str, firstOffsetInNode, len));
      }
      
      firstOffsetInNode = 0;
    }

    if (exit)
      break;

    CheckLeavingBreakElementClosure closure = { mCSSView, PR_FALSE };
    node = FindNextNode(node, mRootNode, CheckLeavingBreakElement, &closure);
    if (closure.mLeftBreakElement || (node && IsBreakElement(mCSSView, node))) {
      // We left, or are entering, a break element (e.g., block). Maybe we can
      // stop now.
      if (seenSoftEnd)
        break;
      // Record the break
      mSoftText.Append(' ');
    }
  }
  
#ifdef DEBUG_SPELLCHECK
  printf("Got DOM string: %s\n", NS_ConvertUTF16toUTF8(mSoftText).get());
#endif
}
示例#13
0
void NodeConvertToBasePtr(      // CONVERT TO A BASE PTR, USING SEARCH_RESULT
    PTREE *a_expr,              // - addr( ptr to be converted )
    TYPE base,                  // - base type
    SEARCH_RESULT *result,      // - search result
    bool positive )             // - true ==> use positive value
{
    target_offset_t vb_offset;  // - offset of vbptr
    vindex vb_index;            // - index in vbtable
    target_offset_t delta;      // - delta for class
    PTREE node;                 // - new node
    PTREE dup;                  // - node containing duplicate of original
    PTREE orig;                 // - original value
    TYPE ref_type;              // - reference type for original value

    node = *a_expr;
    /* references can never be NULL by definition */
    ref_type = TypeReference( NodeType( node ) );
    if( ref_type != NULL ) {
        node->flags |= PTF_PTR_NONZERO;
    }
    if( node->flags & PTF_MEMORY_EXACT ) {
        adjust_by_delta( a_expr, base, result->exact_delta, positive );
    } else if( result->non_virtual ) {
        adjust_by_delta( a_expr, base, result->delta, positive );
    } else {
        PTF_FLAG orig_prop;     // - flags propogated from original
        SYMBOL ibp;             // - inline bound reference parameter
        target_offset_t offset; // - offset to ibp
#if 0
        orig_prop = ( node->flags & PTF_FETCH ) | PTF_LVALUE;
#else
        orig_prop = node->flags & PTF_FETCH;
        if( NULL != ref_type ) {
            orig_prop |= PTF_LVALUE;
        }
#endif
        if( NodeGetIbpSymbol( node, &ibp, &offset ) ) {
            PTREE expr;         // - expression under construction
            unsigned vb_exact;  // - exact offset for conversion
            vb_exact = result->exact_delta;
            if( ! positive ) {
                vb_exact = - vb_exact;
            }
            vb_exact += offset;
            if( NULL == ibp ) {
                expr = NULL;
            } else {
                expr = NodeMakeCallee( ibp );
                expr->cgop = CO_IGNORE;
            }
            expr = NodeUnary( CO_VBASE_FETCH, expr );
            expr = PtdVbaseFetch( expr
                                , result->vb_offset
                                , result->vb_index
                                , result->delta + offset
                                , vb_exact );
            expr->type = base;
            expr->flags = orig_prop;
            node = NodeReplace( node, expr );
        } else {
            dup = NULL;
            if( ! NodePtrNonZero( node ) ) {
                dup = NodeDupExpr( &node );
            }
            vb_offset = result->vb_offset;
            vb_index = result->vb_index;
            node = NodeConvertVirtualPtr( node, base, vb_offset, vb_index );
            delta = result->delta;
            if( delta != 0 ) {
                node = NodeBinary( CO_DOT, node, NodeOffset( delta ) );
                node->type = base;
                node->flags |= orig_prop;
            }
            if( dup != NULL ) {
                orig = NodeDupExpr( &dup );
                node = NodeTestExpr( NodeCompareToZero( orig ), node, dup );
            }
        }
        *a_expr = node;
    }
    if( ref_type != NULL ) {
        (*a_expr)->flags |= PTF_LVALUE;
    }
}
示例#14
0
static PTREE transformVaStart   // TRANSFORM TO CO_VASTART OPCODE
    ( PTREE expr )              // - va_start expression
{
    SYMBOL pre_ellipsis_sym;
    SYMBOL stop;
    SYMBOL curr;
    SYMBOL fn;
    SCOPE caller_arg_scope;
    unsigned offset;
    target_size_t arg_size;
    PTREE arg1;
    PTREE arg2;
    PTREE arg3;
    PTREE valist;

    // second argument -- must be pre-... parameter
    arg1 = expr->u.subtree[1];
    arg2 = arg1->u.subtree[0];
    arg3 = arg2->u.subtree[0];
    pre_ellipsis_sym = PTreeOp( &arg2->u.subtree[1] )->u.symcg.symbol;
    caller_arg_scope = ScopeFunctionScopeInProgress();
    fn = ScopeFunction( caller_arg_scope );
    offset = 0;
    if( ObjModelFunctionReturn( fn->sym_type ) == OMR_CLASS_VAL ) {
        offset += TARGET_PACKING;
    }
    if( SymIsThisMember( fn ) ) {
        offset += TARGET_PACKING;
        if( SymCDtorExtraParm( fn ) ) {
            offset += TARGET_PACKING;
        }
    }
    stop = ScopeOrderedStart( caller_arg_scope );
    curr = NULL;
    for(;;) {
        curr = ScopeOrderedNext( stop, curr );
        if( curr == NULL ) {
            PTreeErrorExpr( expr, ERR_INVALID_VASTART_SYMBOL );
            return( expr );
        }
        if( ObjModelArgument( curr->sym_type ) == OMR_CLASS_REF ) {
            arg_size = TARGET_PACKING;
        } else {
            arg_size = CgMemorySize( curr->sym_type );
            arg_size += TARGET_PACKING - 1;
            arg_size &= ~( TARGET_PACKING - 1 );
        }
        offset += arg_size;
        if( curr == pre_ellipsis_sym ) break;
    }
    if( ScopeOrderedNext( stop, curr ) != NULL ) {
        PTreeErrorExpr( expr, ERR_INVALID_VASTART_SYMBOL );
        return( expr );
    }
    // third argument -- va_list symbol
    valist = arg1->u.subtree[1];
    arg1->u.subtree[1] = NULL;
    if( arg3->u.subtree[1]->u.int_constant == 0 ) {
        // compensate for "void *__alist;" arg in <varargs.h>
        offset -= TARGET_PACKING;
    }
    NodeFreeDupedExpr( expr );
    expr = NodeBinary( CO_VASTART, valist, NodeOffset( offset ) );
    return expr;
}