Пример #1
0
bool ph_var_equal(ph_variant_t *a, ph_variant_t *b)
{
  if (a == b) {
    return true;
  }
  if (a->type != b->type) {
    return false;
  }

  switch (a->type) {
    case PH_VAR_INTEGER:
      return a->u.ival == b->u.ival;
    case PH_VAR_REAL:
      return a->u.dval == b->u.dval;
    case PH_VAR_STRING:
      return ph_string_equal(a->u.sval, b->u.sval);
    case PH_VAR_OBJECT:
      return obj_equal(a, b);
    case PH_VAR_ARRAY:
      return arr_equal(a, b);
    default:
      return false;
  }
}
Пример #2
0
Expr* PrimInliner::tryInline() {
  // Returns the failure result or the result of the primitive (if the
  // primitive can't fail) if the primitive has been inlined; returns
  // NULL otherwise. If the primitive has been inlined but can't fail,
  // the bci in the MethodDecoder is set to the first instruction after
  // the failure block.
  // NB: The comparisons below should be replaced with pointer comparisons
  // comparing with the appropriate vmSymbol. Should fix this at some point.
  char* name  = _pdesc->name();
  Expr* res = NULL;
  switch (_pdesc->group()) {
    case IntArithmeticPrimitive:
      if (number_of_parameters() == 2) {
        Expr* x = parameter(0);
        Expr* y = parameter(1);
        if (equal(name, "primitiveAdd:ifFail:"))			{ res = smi_ArithmeticOp(tAddArithOp, x, y);	break; }
        if (equal(name, "primitiveSubtract:ifFail:"))			{ res = smi_ArithmeticOp(tSubArithOp, x, y);	break; }
        if (equal(name, "primitiveMultiply:ifFail:"))			{ res = smi_ArithmeticOp(tMulArithOp, x, y);	break; }
        if (equal(name, "primitiveDiv:ifFail:"))			{ res = smi_Div(x, y);				break; }
        if (equal(name, "primitiveMod:ifFail:"))			{ res = smi_Mod(x, y);				break; }
        if (equal(name, "primitiveBitAnd:ifFail:"))			{ res = smi_BitOp(tAndArithOp, x, y);		break; }
        if (equal(name, "primitiveBitOr:ifFail:"))			{ res = smi_BitOp(tOrArithOp , x, y);		break; }
        if (equal(name, "primitiveBitXor:ifFail:"))			{ res = smi_BitOp(tXOrArithOp, x, y);		break; }
        if (equal(name, "primitiveRawBitShift:ifFail:"))		{ res = smi_Shift(x, y);			break; }
      }
      break;
    case IntComparisonPrimitive:
      if (number_of_parameters() == 2) {
        Expr* x = parameter(0);
        Expr* y = parameter(1);
        if (equal(name, "primitiveSmallIntegerEqual:ifFail:"))		{ res = smi_Comparison(EQBranchOp, x, y);	break; }
        if (equal(name, "primitiveSmallIntegerNotEqual:ifFail:"))	{ res = smi_Comparison(NEBranchOp, x, y);	break; }
        if (equal(name, "primitiveLessThan:ifFail:"))			{ res = smi_Comparison(LTBranchOp, x, y);	break; }
        if (equal(name, "primitiveLessThanOrEqual:ifFail:"))		{ res = smi_Comparison(LEBranchOp, x, y);	break; }
        if (equal(name, "primitiveGreaterThan:ifFail:"))		{ res = smi_Comparison(GTBranchOp, x, y);	break; }
        if (equal(name, "primitiveGreaterThanOrEqual:ifFail:"))		{ res = smi_Comparison(GEBranchOp, x, y);	break; }
      }
      break;
    case FloatArithmeticPrimitive:
      break;
    case FloatComparisonPrimitive:
      break;
    case ObjArrayPrimitive:
      if (equal(name, "primitiveIndexedObjectSize"))			{ res = array_size();						break; }
      if (equal(name, "primitiveIndexedObjectAt:ifFail:"))		{ res = array_at_ifFail(ArrayAtNode::object_at);		break; }
      if (equal(name, "primitiveIndexedObjectAt:put:ifFail:"))		{ res = array_at_put_ifFail(ArrayAtPutNode::object_at_put);	break; }
      break;
    case ByteArrayPrimitive:
      if (equal(name, "primitiveIndexedByteSize"))			{ res = array_size();						break; }
      if (equal(name, "primitiveIndexedByteAt:ifFail:"))		{ res = array_at_ifFail(ArrayAtNode::byte_at);			break; }
      if (equal(name, "primitiveIndexedByteAt:put:ifFail:"))		{ res = array_at_put_ifFail(ArrayAtPutNode::byte_at_put);	break; }
      break;
    case DoubleByteArrayPrimitive:
      if (equal(name, "primitiveIndexedDoubleByteSize"))		{ res = array_size();						break; }
      if (equal(name, "primitiveIndexedDoubleByteAt:ifFail:"))		{ res = array_at_ifFail(ArrayAtNode::double_byte_at);		break; }
      if (equal(name, "primitiveIndexedDoubleByteCharacterAt:ifFail:"))	{ res = array_at_ifFail(ArrayAtNode::character_at);		break; }
      if (equal(name, "primitiveIndexedDoubleByteAt:put:ifFail:"))	{ res = array_at_put_ifFail(ArrayAtPutNode::double_byte_at_put);break; }
      break;
    case BlockPrimitive:
      if (strncmp(name, "primitiveValue", 14) == 0) 			{ res = block_primitiveValue();		break; }
      break;
    case NormalPrimitive:
      if (strncmp(name, "primitiveNew", 12) == 0) 			{ res = obj_new();			break; }
      if (equal(name, "primitiveShallowCopyIfFail:ifFail:"))		{ res = obj_shallowCopy();		break; }
      if (equal(name, "primitiveEqual:"))				{ res = obj_equal();			break; }
      if (equal(name, "primitiveClass"))				{ res = obj_class(true);		break; }
      if (equal(name, "primitiveClassOf:"))				{ res = obj_class(false);		break; }
      if (equal(name, "primitiveHash"))					{ res = obj_hash(true);			break; }
      if (equal(name, "primitiveHashOf:"))				{ res = obj_hash(false);		break; }
      if (equal(name, "primitiveProxyByteAt:ifFail:"))			{ res = proxy_byte_at();		break; }
      if (equal(name, "primitiveProxyByteAt:put:ifFail:"))		{ res = proxy_byte_at_put();		break; }
      break;
   default:
      fatal1("bad primitive group %d", _pdesc->group());
      break;
  }
 
  if (CompilerDebug) {
    cout(PrintInlining && (res != NULL))->print("%*sinlining %s %s\n", _scope->depth + 2, "", _pdesc->name(),
						_usingUncommonTrap ? "(unc. failure)" : (_cannotFail ? "(cannot fail)" :  ""));
  }
  if (!_usingUncommonTrap && !_cannotFail) theCompiler->reporter->report_prim_failure(_pdesc);
  return res;
}