Expr* PrimInliner::tryTypeCheck() {
  // Check if we have enough type information to prove that the primitive is going to fail;
  // if so, directly compile failure block (important for mixed-mode arithmetic).
  // Returns the failure result if the primitive call has been proven
  // to fail; returns NULL otherwise.
  // Should extend code to do general type compatibility test (including MergeExprs, e.g. for 
  // booleans) -- fix this later.  -Urs 11/95
  int num = number_of_parameters();
  for (int i = 0; i < num; i++) {
    Expr* a = parameter(i);
    if (a->hasKlass()) {
      Expr* primArgType = _pdesc->parameter_klass(i, a->preg(), NULL);
      if (primArgType && primArgType->hasKlass() && (a->klass() != primArgType->klass())) {
        // types differ -> primitive must fail
	return primitiveFailure(failureSymbolForArg(i));
      }
    }
  }
  return NULL;
}
Expr* PrimInliner::obj_class(bool has_receiver) {
  assert_no_failure_block();
  if (has_receiver) assert_receiver();

  Expr*   obj     = parameter(0);
  if (obj->hasKlass()) {
    // constant-fold it
    klassOop k = obj->klass();
    return new ConstantExpr(k, new_ConstPReg(_scope, k), NULL);
  } else {
    SAPReg* resPReg = new SAPReg(_scope);
    InlinedPrimitiveNode* n = NodeFactory::new_InlinedPrimitiveNode(
      InlinedPrimitiveNode::obj_klass, resPReg, NULL, obj->preg()
    );
    _gen->append(n);
    // don't know exactly what it is - just use PIC info
    return new UnknownExpr(resPReg, n);
  }
}