/* * $Id: dotnet.ops 22933 2007-11-21 19:40:01Z paultcochrane $ * Copyright (C) 2006-2007, The Perl Foundation. */ #include "parrot/dynext.h" #include "../pmc/tableinfo.h" #include "../pmc/structures.h" VERSION = PARROT_VERSION; /* Overflow checking macros for add, subtract and multiply. Taken from Mono (http://svn.myrealbox.com/viewcvs/trunk/mono/mono/interp/interp.c). */ #define FALSE 0 #define MAX_UINT4 4294967295U #define MAX_INT4 2147483647 #define MIN_INT4 (-MAX_INT4 -1) #define MAX_UINT8 18446744073709551615 #define MAX_INT8 9223372036854775807 #define MIN_INT8 (-MAX_INT8 -1) #define CHECK_ADD_OVERFLOW(a, b) \ (Parrot_Int4)(b) >= 0 ? \ (Parrot_Int4)(MAX_INT4) - (Parrot_Int4)(b) < (Parrot_Int4)(a) ? -1 : 0 \ : (Parrot_Int4)(MIN_INT4) - (Parrot_Int4)(b) > (Parrot_Int4)(a) ? +1 : 0 #define CHECK_SUB_OVERFLOW(a, b) \ (Parrot_Int4)(b) < 0 ? \ (Parrot_Int4)(MAX_INT4) + (Parrot_Int4)(b) < (Parrot_Int4)(a) ? -1 : 0 \ : (Parrot_Int4)(MIN_INT4) + (Parrot_Int4)(b) > (Parrot_Int4)(a) ? +1 : 0 #define CHECK_ADD_OVERFLOW_UN(a, b) \ (Parrot_UInt4)(MAX_UINT4) - (Parrot_UInt4)(b) < (Parrot_UInt4)(a) ? -1 : 0 #define CHECK_SUB_OVERFLOW_UN(a, b) \ (Parrot_UInt4)(a) < (Parrot_UInt4)(b) ? -1 : 0 #define CHECK_ADD_OVERFLOW64(a, b) \ (HUGEINTVAL)(b) >= 0 ? (HUGEINTVAL)(MAX_INT8) - (HUGEINTVAL)(b) < (HUGEINTVAL)(a) ? -1 : 0 \ : (HUGEINTVAL)(MIN_INT8) - (HUGEINTVAL)(b) > (HUGEINTVAL)(a) ? +1 : 0 #define CHECK_SUB_OVERFLOW64(a, b) \ (HUGEINTVAL)(b) < 0 ? (HUGEINTVAL)(MAX_INT8) + (HUGEINTVAL)(b) < (HUGEINTVAL)(a) ? -1 : 0 \ : (HUGEINTVAL)(MIN_INT8) + (HUGEINTVAL)(b) > (HUGEINTVAL)(a) ? +1 : 0 #define CHECK_ADD_OVERFLOW64_UN(a, b) \ (UHUGEINTVAL)(MAX_UINT8) - (UHUGEINTVAL)(b) < (UHUGEINTVAL)(a) ? -1 : 0 #define CHECK_SUB_OVERFLOW64_UN(a, b) \ (UHUGEINTVAL)(a) < (UHUGEINTVAL)(b) ? -1 : 0 #define CHECK_MUL_OVERFLOW(a, b) \ ((Parrot_Int4)(a) == 0) || ((Parrot_Int4)(b) == 0) ? 0 : \ (((Parrot_Int4)(a) > 0) && ((Parrot_Int4)(b) == -1)) ? FALSE : \ (((Parrot_Int4)(a) < 0) && ((Parrot_Int4)(b) == -1)) ? (a == - MAX_INT4) : \ (((Parrot_Int4)(a) > 0) && ((Parrot_Int4)(b) > 0)) ? \ (Parrot_Int4)(a) > ((MAX_INT4) / (Parrot_Int4)(b)) : \ (((Parrot_Int4)(a) > 0) && ((Parrot_Int4)(b) < 0)) ? \ (Parrot_Int4)(a) > ((MIN_INT4) / (Parrot_Int4)(b)) : \ (((Parrot_Int4)(a) < 0) && ((Parrot_Int4)(b) > 0)) ? \ (Parrot_Int4)(a) < ((MIN_INT4) / (Parrot_Int4)(b)) : \ (Parrot_Int4)(a) < ((MAX_INT4) / (Parrot_Int4)(b)) #define CHECK_MUL_OVERFLOW_UN(a, b) \ ((Parrot_UInt4)(a) == 0) || ((Parrot_UInt4)(b) == 0) ? 0 : \ (Parrot_UInt4)(b) > ((MAX_UINT4) / (Parrot_UInt4)(a)) #define CHECK_MUL_OVERFLOW64(a, b) \ ((HUGEINTVAL)(a) == 0) || ((HUGEINTVAL)(b) == 0) ? 0 : \ (((HUGEINTVAL)(a) > 0) && ((HUGEINTVAL)(b) == -1)) ? FALSE : \ (((HUGEINTVAL)(a) < 0) && ((HUGEINTVAL)(b) == -1)) ? (a == - MAX_INT8) : \ (((HUGEINTVAL)(a) > 0) && ((HUGEINTVAL)(b) > 0)) ? \ (HUGEINTVAL)(a) > ((MAX_INT8) / (HUGEINTVAL)(b)) : \ (((HUGEINTVAL)(a) > 0) && ((HUGEINTVAL)(b) < 0)) ? \ (HUGEINTVAL)(a) > ((MIN_INT8) / (HUGEINTVAL)(b)) : \ (((HUGEINTVAL)(a) < 0) && ((HUGEINTVAL)(b) > 0)) ? \ (HUGEINTVAL)(a) < ((MIN_INT8) / (HUGEINTVAL)(b)) : \ (HUGEINTVAL)(a) < ((MAX_INT8) / (HUGEINTVAL)(b)) #define CHECK_MUL_OVERFLOW64_UN(a, b) \ ((UHUGEINTVAL)(a) == 0) || ((UHUGEINTVAL)(b) == 0) ? 0 : \ (UHUGEINTVAL)(b) > ((MAX_UINT8) / (UHUGEINTVAL)(a)) /* Overflow exception thrower. */ static opcode_t* dotnet_OverflowException(Parrot_Interp interp, opcode_t *ret) { PMC *ex_pmc = pmc_new(interp, enum_class_Exception); VTABLE_set_string_native(interp, ex_pmc, string_from_literal(interp, "System.OverflowException")); return (opcode_t *)throw_exception(interp, ex_pmc, ret); } /* Unsigned arithmetic ops. */ inline op net_div_un(out INT, in INT, in INT) :base_core { $1 = ((unsigned int) $2) / ((unsigned int) $3); goto NEXT(); } inline op net_div_un(out PMC, invar PMC, invar PMC) :base_core { if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64* i = mem_sys_allocate(sizeof (struct dotnet_uint64)); struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); PMC_struct_val($1) = i; i->x = i1->x / i2->x; } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 / i2); } goto NEXT(); } inline op net_rem_un(out INT, in INT, in INT) :base_core { $1 = ((unsigned int) $2) % ((unsigned int) $3); goto NEXT(); } inline op net_rem_un(out PMC, invar PMC, invar PMC) :base_core { if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64* i = mem_sys_allocate(sizeof (struct dotnet_uint64)); struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); PMC_struct_val($1) = i; i->x = i1->x % i2->x; } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 % i2); } goto NEXT(); } /* Overflow checked arithmetic ops. */ inline op net_add_ovf(out INT, in INT, in INT) :base_core { if (CHECK_ADD_OVERFLOW($2, $3)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = $2 + $3; goto NEXT(); } } inline op net_add_ovf(out PMC, invar PMC, invar PMC) :base_core { opcode_t *ret = expr NEXT(); if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i1 = PMC_struct_val($2); struct dotnet_int64 *i2 = PMC_struct_val($3); if (CHECK_ADD_OVERFLOW64(i1->x, i2->x)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_int64* i = mem_sys_allocate(sizeof (struct dotnet_int64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Int64"))); PMC_struct_val($1) = i; i->x = i1->x + i2->x; goto NEXT(); } } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); if (CHECK_ADD_OVERFLOW(i1, i2)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 + i2); goto NEXT(); } } } inline op net_add_ovf_un(out INT, in INT, in INT) :base_core { if (CHECK_ADD_OVERFLOW_UN($2, $3)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = ((unsigned int) $2) + ((unsigned int) $3); goto NEXT(); } } inline op net_add_ovf_un(out PMC, invar PMC, invar PMC) :base_core { opcode_t *ret = expr NEXT(); if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); if (CHECK_ADD_OVERFLOW64_UN(i1->x, i2->x)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_uint64* i = mem_sys_allocate(sizeof (struct dotnet_uint64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); PMC_struct_val($1) = i; i->x = i1->x + i2->x; goto NEXT(); } } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); if (CHECK_ADD_OVERFLOW_UN(i1, i2)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 + i2); goto NEXT(); } } } inline op net_sub_ovf(out INT, in INT, in INT) :base_core { if (CHECK_SUB_OVERFLOW($2, $3)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = $2 - $3; goto NEXT(); } } inline op net_sub_ovf(out PMC, invar PMC, invar PMC) :base_core { opcode_t *ret = expr NEXT(); if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i1 = PMC_struct_val($2); struct dotnet_int64 *i2 = PMC_struct_val($3); if (CHECK_SUB_OVERFLOW64(i1->x, i2->x)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_int64* i = mem_sys_allocate(sizeof (struct dotnet_int64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Int64"))); PMC_struct_val($1) = i; i->x = i1->x - i2->x; goto NEXT(); } } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); if (CHECK_SUB_OVERFLOW(i1, i2)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 - i2); goto NEXT(); } } } inline op net_sub_ovf_un(out INT, in INT, in INT) :base_core { if (CHECK_SUB_OVERFLOW_UN($2, $3)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = ((unsigned int) $2) - ((unsigned int) $3); goto NEXT(); } } inline op net_sub_ovf_un(out PMC, invar PMC, invar PMC) :base_core { opcode_t *ret = expr NEXT(); if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); if (CHECK_SUB_OVERFLOW64_UN(i1->x, i2->x)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_uint64* i = mem_sys_allocate(sizeof (struct dotnet_uint64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); PMC_struct_val($1) = i; i->x = i1->x - i2->x; goto NEXT(); } } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); if (CHECK_SUB_OVERFLOW_UN(i1, i2)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 - i2); goto NEXT(); } } } inline op net_mul_ovf(out INT, in INT, in INT) :base_core { if (CHECK_MUL_OVERFLOW($2, $3)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = $2 * $3; goto NEXT(); } } inline op net_mul_ovf(out PMC, invar PMC, invar PMC) :base_core { opcode_t *ret = expr NEXT(); if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); if (CHECK_MUL_OVERFLOW64(i1->x, i2->x)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_int64* i = mem_sys_allocate(sizeof (struct dotnet_int64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Int64"))); PMC_struct_val($1) = i; i->x = i1->x * i2->x; goto NEXT(); } } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); if (CHECK_MUL_OVERFLOW(i1, i2)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 * i2); goto NEXT(); } } } inline op net_mul_ovf_un(out INT, in INT, in INT) :base_core { if (CHECK_MUL_OVERFLOW_UN($2, $3)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = ((unsigned int) $2) * ((unsigned int) $3); goto NEXT(); } } inline op net_mul_ovf_un(out PMC, invar PMC, invar PMC) :base_core { opcode_t *ret = expr NEXT(); if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); if (CHECK_MUL_OVERFLOW64_UN(i1->x, i2->x)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_uint64* i = mem_sys_allocate(sizeof (struct dotnet_uint64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); PMC_struct_val($1) = i; i->x = i1->x * i2->x; goto NEXT(); } } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); if (CHECK_MUL_OVERFLOW_UN(i1, i2)) { opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Integer"))); $1->vtable->set_integer_native(interp, $1, i1 * i2); goto NEXT(); } } } /* Unsigned comparison ops. */ inline op net_cgt_un(out INT, in INT, in INT) :base_core { $1 = ((unsigned int) $2) > ((unsigned int) $3) ? 1 : 0; goto NEXT(); } inline op net_cgt_un(out INT, in NUM, in NUM) :base_core { $1 = $2 > $3 ? 1 : 0; goto NEXT(); } inline op net_cgt_un(out INT, invar PMC, invar PMC) :base_core { if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); $1 = i1->x > i2->x ? 1 : 0; } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); $1 = i1 > i2 ? 1 : 0; } goto NEXT(); } inline op net_clt_un(out INT, in INT, in INT) :base_core { $1 = ((unsigned int) $2) < ((unsigned int) $3) ? 1 : 0; goto NEXT(); } inline op net_clt_un(out INT, in NUM, in NUM) :base_core { $1 = $2 < $3 ? 1 : 0; goto NEXT(); } inline op net_clt_un(out INT, invar PMC, invar PMC) :base_core { if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($2); struct dotnet_uint64 *i2 = PMC_struct_val($3); $1 = i1->x < i2->x ? 1 : 0; } else { int i1 = $2->vtable->get_integer(interp, $2); int i2 = $3->vtable->get_integer(interp, $3); $1 = i1 < i2 ? 1 : 0; } goto NEXT(); } /* Unsigned branch ops. */ inline op net_bge_un(in INT, in INT, labelconst INT) :base_core { if ((unsigned int)$1 >= (unsigned int)$2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bge_un(in NUM, in NUM, labelconst INT) :base_core { if ((unsigned int)$1 >= (unsigned int)$2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bge_un(invar PMC, invar PMC, labelconst INT) :base_core { int result; if ($1->vtable->isa(interp, $1, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($1); struct dotnet_uint64 *i2 = PMC_struct_val($2); result = i1->x >= i2->x ? 1 : 0; } else { int i1 = $1->vtable->get_integer(interp, $1); int i2 = $2->vtable->get_integer(interp, $2); result = i1 >= i2 ? 1 : 0; } if (result) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bgt_un(in INT, in INT, labelconst INT) :base_core { if ((unsigned int)$1 > (unsigned int)$2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bgt_un(in NUM, in NUM, labelconst INT) :base_core { if ($1 > $2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bgt_un(invar PMC, invar PMC, labelconst INT) :base_core { int result; if ($1->vtable->isa(interp, $1, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($1); struct dotnet_uint64 *i2 = PMC_struct_val($2); result = i1->x > i2->x ? 1 : 0; } else { int i1 = $1->vtable->get_integer(interp, $1); int i2 = $2->vtable->get_integer(interp, $2); result = i1 > i2 ? 1 : 0; } if (result) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_ble_un(in INT, in INT, labelconst INT) :base_core { if ((unsigned int)$1 <= (unsigned int)$2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_ble_un(in NUM, in NUM, labelconst INT) :base_core { if ($1 <= $2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_ble_un(invar PMC, invar PMC, labelconst INT) :base_core { int result; if ($1->vtable->isa(interp, $1, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($1); struct dotnet_uint64 *i2 = PMC_struct_val($2); result = i1->x <= i2->x ? 1 : 0; } else { int i1 = $1->vtable->get_integer(interp, $1); int i2 = $2->vtable->get_integer(interp, $2); result = i1 <= i2 ? 1 : 0; } if (result) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_blt_un(in INT, in INT, labelconst INT) :base_core { if ((unsigned int)$1 < (unsigned int)$2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_blt_un(in NUM, in NUM, labelconst INT) :base_core { if ($1 < $2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_blt_un(invar PMC, invar PMC, labelconst INT) :base_core { int result; if ($1->vtable->isa(interp, $1, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($1); struct dotnet_uint64 *i2 = PMC_struct_val($2); result = i1->x < i2->x ? 1 : 0; } else { int i1 = $1->vtable->get_integer(interp, $1); int i2 = $2->vtable->get_integer(interp, $2); result = i1 < i2 ? 1 : 0; } if (result) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bne_un(in INT, in INT, labelconst INT) :base_core { if ((unsigned int)$1 != (unsigned int)$2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bne_un(in NUM, in NUM, labelconst INT) :base_core { if ($1 != $2) { goto OFFSET($3); } else { goto NEXT(); } } inline op net_bne_un(invar PMC, invar PMC, labelconst INT) :base_core { int result; if ($1->vtable->isa(interp, $1, string_from_literal(interp, "UInt64"))) { struct dotnet_uint64 *i1 = PMC_struct_val($1); struct dotnet_uint64 *i2 = PMC_struct_val($2); result = i1->x != i2->x ? 1 : 0; } else { result = $1 != $2 ? 1 : 0; } if (result) { goto OFFSET($3); } else { goto NEXT(); } } /* Unchecked conversion ops. */ inline op net_conv_i1(out INT, in INT) :base_core { $1 = (Parrot_Int1) $2; goto NEXT(); } inline op net_conv_i1(out INT, in NUM) :base_core { $1 = (Parrot_Int1) $2; goto NEXT(); } inline op net_conv_i1(out INT, invar PMC) :base_core { $1 = (Parrot_Int1) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_u1(out INT, in INT) :base_core { $1 = (Parrot_UInt1) $2; goto NEXT(); } inline op net_conv_u1(out INT, in NUM) :base_core { $1 = (Parrot_UInt1) $2; goto NEXT(); } inline op net_conv_u1(out INT, invar PMC) :base_core { $1 = (Parrot_UInt1) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_i2(out INT, in INT) :base_core { $1 = (Parrot_Int2) $2; goto NEXT(); } inline op net_conv_i2(out INT, in NUM) :base_core { $1 = (Parrot_Int2) ((Parrot_Int4) $2); goto NEXT(); } inline op net_conv_i2(out INT, invar PMC) :base_core { $1 = (Parrot_Int2) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_u2(out INT, in INT) :base_core { $1 = (Parrot_UInt2) $2; goto NEXT(); } inline op net_conv_u2(out INT, in NUM) :base_core { $1 = (Parrot_UInt2) $2; goto NEXT(); } inline op net_conv_u2(out INT, invar PMC) :base_core { $1 = (Parrot_UInt2) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_i4(out INT, in INT) :base_core { $1 = (Parrot_Int4) $2; goto NEXT(); } inline op net_conv_i4(out INT, in NUM) :base_core { $1 = (Parrot_Int4) $2; goto NEXT(); } inline op net_conv_i4(out INT, invar PMC) :base_core { $1 = (Parrot_Int4) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_u4(out INT, in INT) :base_core { $1 = (Parrot_UInt4) $2; goto NEXT(); } inline op net_conv_u4(out INT, in NUM) :base_core { $1 = (Parrot_UInt4) $2; goto NEXT(); } inline op net_conv_u4(out INT, invar PMC) :base_core { $1 = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_i8(out PMC, in INT) :base_core { PMC* i8 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Int64"))); struct dotnet_int64* i = mem_sys_allocate(sizeof (struct dotnet_int64)); PMC_struct_val(i8) = i; i->x = $2; $1 = i8; goto NEXT(); } inline op net_conv_i8(out PMC, in NUM) :base_core { PMC* i8 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Int64"))); struct dotnet_int64* i = mem_sys_allocate(sizeof (struct dotnet_int64)); PMC_struct_val(i8) = i; i->x = (HUGEINTVAL) $2; $1 = i8; goto NEXT(); } inline op net_conv_u8(out PMC, in INT) :base_core { PMC* u8 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); struct dotnet_uint64* ui = mem_sys_allocate(sizeof (struct dotnet_uint64)); PMC_struct_val(u8) = ui; ui->x = $2; $1 = u8; goto NEXT(); } inline op net_conv_u8(out PMC, in NUM) :base_core { PMC* u8 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); struct dotnet_uint64* ui = mem_sys_allocate(sizeof (struct dotnet_uint64)); PMC_struct_val(u8) = ui; ui->x = (UHUGEINTVAL) $2; $1 = u8; goto NEXT(); } inline op net_conv_r4(out NUM, in INT) :base_core { $1 = (Parrot_Float4) $2; goto NEXT(); } inline op net_conv_r4(out NUM, in NUM) :base_core { $1 = (Parrot_Float4) $2; goto NEXT(); } inline op net_conv_r4(out NUM, invar PMC) :base_core { $1 = (Parrot_Float) $2->vtable->get_number(interp, $2); goto NEXT(); } inline op net_conv_r8(out NUM, in INT) :base_core { $1 = (Parrot_Float8) $2; goto NEXT(); } inline op net_conv_r8(out NUM, in NUM) :base_core { $1 = (Parrot_Float8) $2; goto NEXT(); } inline op net_conv_r8(out NUM, invar PMC) :base_core { $1 = (Parrot_Float) $2->vtable->get_number(interp, $2); goto NEXT(); } inline op net_conv_i(out INT, in INT) :base_core { $1 = (int) $2; goto NEXT(); } inline op net_conv_i(out INT, in NUM) :base_core { $1 = (int) $2; goto NEXT(); } inline op net_conv_i(out INT, invar PMC) :base_core { $1 = (int) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_u(out INT, in INT) :base_core { $1 = (unsigned int) $2; goto NEXT(); } inline op net_conv_u(out INT, in NUM) :base_core { $1 = (unsigned int) $2; goto NEXT(); } inline op net_conv_u(out INT, invar PMC) :base_core { $1 = (unsigned int) $2->vtable->get_integer(interp, $2); goto NEXT(); } inline op net_conv_r_un(out NUM, in INT) :base_core { $1 = (Parrot_Float) ((unsigned int) $2); goto NEXT(); } inline op net_conv_r_un(out NUM, invar PMC) :base_core { if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_int64 *i = PMC_struct_val($2); $1 = (Parrot_Float) i->x; } else { $1 = (Parrot_Float) $2->vtable->get_integer(interp, $2); } goto NEXT(); } /* Checked conversion ops. */ inline op net_conv_ovf_i1_un(out INT, in INT) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0x7F) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int1) tmp; goto NEXT(); } } inline op net_conv_ovf_i1_un(out INT, invar PMC) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); if (tmp > 0x7F) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int1) tmp; goto NEXT(); } } inline op net_conv_ovf_u1_un(out INT, in INT) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0xFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt1) tmp; goto NEXT(); } } inline op net_conv_ovf_u1_un(out INT, invar PMC) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); if (tmp > 0xFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt1) tmp; goto NEXT(); } } inline op net_conv_ovf_i2_un(out INT, in INT) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0x7FFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int2) tmp; goto NEXT(); } } inline op net_conv_ovf_i2_un(out INT, invar PMC) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); if (tmp > 0x7FFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int2) tmp; goto NEXT(); } } inline op net_conv_ovf_u2_un(out INT, in INT) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0xFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt2) tmp; goto NEXT(); } } inline op net_conv_ovf_u2_un(out INT, invar PMC) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); if (tmp > 0xFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt2) tmp; goto NEXT(); } } inline op net_conv_ovf_i4_un(out INT, in INT) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0x7FFFFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int4) tmp; goto NEXT(); } } inline op net_conv_ovf_i4_un(out INT, invar PMC) :base_core { int ok = 1; if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x > 0x7FFFFFFF) ok = 0; } else { if ($2->vtable->get_integer(interp, $2) > 0x7FFFFFFF) ok = 0; } if (!ok) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); goto NEXT(); } } inline op net_conv_ovf_u4_un(out INT, in INT) :base_core { Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0xFFFFFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt4) tmp; goto NEXT(); } } inline op net_conv_ovf_u4_un(out INT, invar PMC) :base_core { int ok = 1; if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x > 0xFFFFFFFF) ok = 0; } else { if ($2->vtable->get_integer(interp, $2) > 0xFFFFFFFF) ok = 0; } if (!ok) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt4) $2->vtable->get_integer(interp, $2); goto NEXT(); } } inline op net_conv_ovf_i_un(out INT, in INT) :base_core { /* RT#42349 Fix for 64-bit architecture. */ Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0x7FFFFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (int) tmp; goto NEXT(); } } inline op net_conv_ovf_u_un(out INT, in INT) :base_core { /* RT#42349 Fix for 64-bit architecture. */ Parrot_UInt4 tmp = (Parrot_UInt4) $2; if (tmp > 0xFFFFFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (unsigned int) tmp; goto NEXT(); } } inline op net_conv_ovf_i1(out INT, in INT) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp > 0x7F || tmp < ((Parrot_Int1) 0x80)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int1) tmp; goto NEXT(); } } inline op net_conv_ovf_i1(out INT, invar PMC) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2->vtable->get_integer(interp, $2); if (tmp > 0x7F || tmp < ((Parrot_Int1) 0x80)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int1) tmp; goto NEXT(); } } inline op net_conv_ovf_u1(out INT, in INT) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp < 0 || tmp > 0xFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt1) tmp; goto NEXT(); } } inline op net_conv_ovf_u1(out INT, invar PMC) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2->vtable->get_integer(interp, $2); if (tmp < 0 || tmp > 0xFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt1) tmp; goto NEXT(); } } inline op net_conv_ovf_i2(out INT, in INT) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp > 0x7FFF || tmp < ((Parrot_Int2) 0x8000)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int2) tmp; goto NEXT(); } } inline op net_conv_ovf_i2(out INT, invar PMC) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2->vtable->get_integer(interp, $2); if (tmp > 0x7FFF || tmp < ((Parrot_Int2) 0x8000)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int2) tmp; goto NEXT(); } } inline op net_conv_ovf_u2(out INT, in INT) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp < 0 || tmp > 0xFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt2) tmp; goto NEXT(); } } inline op net_conv_ovf_u2(out INT, invar PMC) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2->vtable->get_integer(interp, $2); if (tmp < 0 || tmp > 0xFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt2) tmp; goto NEXT(); } } inline op net_conv_ovf_i4(out INT, in INT) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp > 0x7FFFFFFF || tmp < ((Parrot_Int4) 0x80000000)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int4) tmp; goto NEXT(); } } inline op net_conv_ovf_i4(out INT, invar PMC) :base_core { int ok = 1; if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x > 0x7FFFFFFF) ok = 0; } else if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x > 0x7FFFFFFF) ok = 0; } else { if ($2->vtable->get_integer(interp, $2) > 0x7FFFFFFF) ok = 0; } if (!ok) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int4) $2->vtable->get_integer(interp, $2); goto NEXT(); } } inline op net_conv_ovf_u4(out INT, in INT) :base_core { Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp < 0 || tmp > 0xFFFFFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt4) tmp; goto NEXT(); } } inline op net_conv_ovf_u4(out INT, invar PMC) :base_core { int ok = 1; if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x < 0 || i->x > 0xFFFFFFFF) ok = 0; } else if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x < 0 || i->x > 0xFFFFFFFF) ok = 0; } else { if ($2->vtable->get_integer(interp, $2) > 0xFFFFFFFF || $2->vtable->get_integer(interp, $2) < 0) ok = 0; } if (!ok) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int4) $2->vtable->get_integer(interp, $2); goto NEXT(); } } inline op net_conv_ovf_i(out INT, in INT) :base_core { /* RT#42349 Fix for 64-bit architecture. */ Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp > 0x7FFFFFFF || tmp < ((Parrot_Int4) 0x80000000)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (int) tmp; goto NEXT(); } } inline op net_conv_ovf_i(out INT, invar PMC) :base_core { /* RT#42349 Fix for 64-bit architecture. */ int ok = 1; if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x > 0x7FFFFFFF) ok = 0; } else if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x > 0x7FFFFFFF) ok = 0; } else { if ($2->vtable->get_integer(interp, $2) > 0x7FFFFFFF) ok = 0; } if (!ok) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (int) $2->vtable->get_integer(interp, $2); goto NEXT(); } } inline op net_conv_ovf_u(out INT, in INT) :base_core { /* RT#42349 Fix for 64-bit architecture. */ Parrot_Int4 tmp = (Parrot_Int4) $2; if (tmp < 0 || tmp > 0xFFFFFFFF) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (unsigned int) tmp; goto NEXT(); } } inline op net_conv_ovf_u(out INT, invar PMC) :base_core { /* RT#42349 Fix for 64-bit architecture. */ int ok = 1; if ($2->vtable->isa(interp, $2, string_from_literal(interp, "Int64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x < 0 || i->x > 0xFFFFFFFF) ok = 0; } else if ($2->vtable->isa(interp, $2, string_from_literal(interp, "UInt64"))) { struct dotnet_int64 *i = PMC_struct_val($2); if (i->x < 0 || i->x > 0xFFFFFFFF) ok = 0; } else { if ($2->vtable->get_integer(interp, $2) > 0xFFFFFFFF || $2->vtable->get_integer(interp, $2) < 0) ok = 0; } if (!ok) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (unsigned int) $2->vtable->get_integer(interp, $2); goto NEXT(); } } inline op net_conv_ovf_i1(out INT, in NUM) :base_core { if ($2 > ((Parrot_Float) 0x7F) || $2 < ((Parrot_Float) ((Parrot_Int1) 0x80))) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int1) $2; goto NEXT(); } } inline op net_conv_ovf_u1(out INT, in NUM) :base_core { if ($2 < 0 || $2 > ((Parrot_Float) 0xFF)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt1) $2; goto NEXT(); } } inline op net_conv_ovf_i2(out INT, in NUM) :base_core { if ($2 > ((Parrot_Float) 0x7FFF) || $2 < ((Parrot_Float) ((Parrot_Int2) 0x8000))) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int2) $2; goto NEXT(); } } inline op net_conv_ovf_u2(out INT, in NUM) :base_core { if ($2 < 0 || $2 > ((Parrot_Float) 0xFFFF)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt2) $2; goto NEXT(); } } inline op net_conv_ovf_i4(out INT, in NUM) :base_core { if ($2 > ((Parrot_Float) 0x7FFFFFFF) || $2 < ((Parrot_Float) ((Parrot_Int4) 0x80000000))) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_Int4) $2; goto NEXT(); } } inline op net_conv_ovf_u4(out INT, in NUM) :base_core { if ($2 < 0 || $2 > ((Parrot_Float) 0xFFFFFFFF)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (Parrot_UInt4) $2; goto NEXT(); } } inline op net_conv_ovf_i8(out PMC, in NUM) :base_core { if ($2 > ((Parrot_Float) MAX_INT8) || $2 < ((Parrot_Float) ((Parrot_Int4) MIN_INT8))) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_int64* i = mem_sys_allocate(sizeof (struct dotnet_int64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "Int64"))); PMC_struct_val($1) = i; i->x = (HUGEINTVAL) $2; goto NEXT(); } } inline op net_conv_ovf_u8(out PMC, in NUM) :base_core { if ($2 > ((Parrot_Float) MAX_UINT8) || $2 < 0) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { struct dotnet_uint64* i = mem_sys_allocate(sizeof (struct dotnet_uint64)); $1 = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "UInt64"))); PMC_struct_val($1) = i; i->x = (UHUGEINTVAL) $2; goto NEXT(); } } inline op net_conv_ovf_i(out INT, in NUM) :base_core { /* RT#42349 Fix for 64-bit architecture. */ if ($2 > ((Parrot_Float) 0x7FFFFFFF) || $2 < ((Parrot_Float) ((Parrot_Int4) 0x80000000))) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (int) $2; goto NEXT(); } } inline op net_conv_ovf_u(out INT, in NUM) :base_core { /* RT#42349 Fix for 64-bit architecture. */ if ($2 < 0 || $2 > ((Parrot_Float) 0xFFFFFFFF)) { opcode_t *ret = expr NEXT(); opcode_t *dest = dotnet_OverflowException(interp, ret); goto ADDRESS(dest); } else { $1 = (unsigned int) $2; goto NEXT(); } } /* Ops related to managed pointers. */ inline op net_ldelema(out PMC, invar PMC, in INT) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Stash away array details inside the pointer struct. */ managed_ptr->type = PTR_TYPE_ELEMENT; managed_ptr->pmc = $2; managed_ptr->index = $3; /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } inline op net_ldelema(out PMC, invar PMC, invar PMC) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Stash away array details inside the pointer struct. */ managed_ptr->type = PTR_TYPE_ELEMENT; managed_ptr->pmc = $2; managed_ptr->index = VTABLE_get_integer(interp, $3); /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } inline op net_ldflda(out PMC, invar PMC, in STR) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Stash away field details inside the pointer struct. */ managed_ptr->type = PTR_TYPE_FIELD; managed_ptr->pmc = $2; managed_ptr->name = $3; /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } inline op net_reg_ptr(out PMC, in INT) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Set up the pointer to the register. */ managed_ptr->type = PTR_TYPE_REGISTER; managed_ptr->ctx = interp->ctx.state; managed_ptr->r.reg_type = PTR_REGTYPE_I; managed_ptr->r.number = CUR_OPCODE[2]; /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } inline op net_reg_ptr(out PMC, in NUM) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Set up the pointer to the register. */ managed_ptr->type = PTR_TYPE_REGISTER; managed_ptr->ctx = interp->ctx.state; managed_ptr->r.reg_type = PTR_REGTYPE_N; managed_ptr->r.number = CUR_OPCODE[2]; /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } inline op net_reg_ptr(out PMC, invar PMC) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Set up the pointer to the register. */ managed_ptr->type = PTR_TYPE_REGISTER; managed_ptr->ctx = interp->ctx.state; managed_ptr->r.reg_type = PTR_REGTYPE_P; managed_ptr->r.number = CUR_OPCODE[2]; /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } inline op net_pmc_ptr(out PMC, invar PMC) :base_core { /* Create PMC, underlying struct and tie them together. */ PMC* mp = pmc_new(interp, pmc_type(interp, string_from_literal(interp, "ManagedPointer"))); struct dotnet_managed_ptr* managed_ptr = mem_sys_allocate( sizeof (struct dotnet_managed_ptr)); PMC_struct_val(mp) = managed_ptr; /* Set up the pointer to the PMC. */ managed_ptr->type = PTR_TYPE_PMC; managed_ptr->pmc = $2; /* Hand back managed pointer PMC. */ $1 = mp; goto NEXT(); } /* Op to get the address of a PMC. */ inline op net_pmc_addr(out INT, invar PMC) :base_core { $1 = (int) $2; goto NEXT(); } /* * Local variables: * c-file-style: "parrot" * End: * vim: expandtab shiftwidth=4: */