static int fegetexcept (void) { static fenv_t fenv; return fegetenv (&fenv) ? -1 : (fenv.__control & FE_ALL_EXCEPT); }
void FloatingPointEnvironment::saveMainThreadEnvironment() { RELEASE_ASSERT(!m_isInitialized); RELEASE_ASSERT(isUIThread()); fegetenv(&m_mainThreadEnvironment); m_isInitialized = true; }
int feclearexcept(int e) { fenv_t ft; fegetenv(&ft); ft.__status &= ~e; fesetenv(&ft); return 0; }
/* GNU C Library: http://www.gnu.org/software/libc/manual/html_node/Control-Functions.html - Function: int fegetexcept (int excepts) The function returns a bitmask of all currently enabled exceptions. It returns -1 in case of failure. The excepts argument appears in other functions in fenv.h, and corresponds to the FE_xxx exception flag constants. It is unclear whether the bitmask is for the flags or the masks. We return that for the flags, which corresponds to the excepts argument in feenableexcept(excepts) and fedisableexcept(excepts). In GNU/Linux the argument is void, and that's what we implement. Linux "man fegetenv" appears to suggest that it's the mask corresponding to bits in excepts that is returned. */ static int fegetexcept (void) { static fenv_t fenv; return ( fegetenv (&fenv) ? -1 : ( ( fenv & (FM_ALL_EXCEPT) ) << FE_EXCEPT_SHIFT ) ); }
int feholdexcept (fenv_t *envp) { /* Store the environment. */ fegetenv (envp); /* Clear the current sticky bits as more than one exception may be generated. */ envp->fpc &= ~(FPC_FLAGS_MASK | FPC_DXC_MASK); /* Hold from generating fpu exceptions temporarily. */ _FPU_SETCW ((envp->fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT))); return 0; }
/* * This tests checks the default FP environment, so it must be first. * The memcmp() test below may be too much to ask for, since there * could be multiple machine-specific default environments. */ static void test_dfl_env(void) { #ifndef NO_STRICT_DFL_ENV fenv_t env; fegetenv(&env); assert(memcmp(&env, FE_DFL_ENV, sizeof(env)) == 0); #endif assert(fetestexcept(FE_ALL_EXCEPT) == 0); }
void FloatingPointEnvironment::enableDenormalSupport() { RELEASE_ASSERT(isUIThread()); #if defined _ARM_ARCH_7 fenv_t env; fegetenv(&env); env.__fpscr &= ~0x01000000U; fesetenv(&env); #endif // Supporting denormal mode is already the default on x86, x86_64, and ARM64. }
static int fedisableexcept( unsigned int excepts ) { fenv_t fenv; unsigned int still_on = ~( (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT ), old_excepts; // previous masks if ( fegetenv (&fenv) ) return -1; old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT; fenv &= still_on; return ( fesetenv (&fenv) ? -1 : old_excepts ); }
FlushToZero::FlushToZero() { #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) _controlfp_s(&previous_state, _MCW_DN, _DN_FLUSH); #elif defined(__APPLE__) fegetenv(&previous_state); fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV); #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) previous_state = _mm_getcsr() & _MM_DENORMALS_ZERO_MASK; _mm_setcsr(_mm_getcsr() | (_MM_DENORMALS_ZERO_ON)); #endif }
static int feenableexcept( unsigned int excepts ) { fenv_t fenv; unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT, old_excepts; // all previous masks if ( fegetenv (&fenv) ) return -1; old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT; fenv = (fenv & ~new_excepts) | new_excepts; return ( fesetenv (&fenv) ? -1 : old_excepts ); }
_STD_END #else /* _FPP_TYPE == _FPP_NONE */ _STD_BEGIN int (fegetexceptflag)(fexcept_t *pflag, int except) { /* store selected exception sticky bits */ if ((except &= FE_ALL_EXCEPT) != 0) { /* try to get one or more exception sticky bits */ #if _FPP_TYPE == _FPP_X86 asm("movl 8(%ebp),%eax"); /* gcc/PC */ asm("fstsw (%eax)"); #elif _FPP_TYPE == _FPP_SPARC || _FPP_TYPE == _FPP_S390 \ || _FPP_TYPE == _FPP_MIPS || _FPP_TYPE == _FPP_PPC \ || _FPP_TYPE == _FPP_ALPHA || _FPP_TYPE == _FPP_ARM \ || _FPP_TYPE == _FPP_SH4 || _FPP_TYPE == _FPP_IA64 fegetenv(pflag); *pflag >>= _FE_EXCEPT_OFF; #elif _FPP_TYPE == _FPP_HPPA || _FPP_TYPE == _FPP_M68K *pflag = _Fegetstat(); *pflag >>= _FE_EXCEPT_OFF; #elif _FPP_TYPE == _FPP_WCE fenv_t env; fegetenv(&env); *pflag = env._Fe_stat >> _FE_EXCEPT_OFF; #else /* _FPP_TYPE */ #error unknown FPP type #endif /* _FPP_TYPE */ } *pflag &= except; return (0); }
int fesetexceptflag(const fexcept_t *f, int e) { fenv_t ft; unsigned short sw; fegetenv(&ft); sw = *f; sw &= e; ft.__status_uint16_t = sw; fesetenv(&ft); return 0; }
int fedisableexcept(unsigned int excepts) { static fenv_t fenv; unsigned int new_excepts = excepts & FE_ALL_EXCEPT, old_excepts; if (fegetenv(&fenv)) return -1; old_excepts = fenv.__control & FE_ALL_EXCEPT; // mask fenv.__control |= new_excepts; fenv.__mxcsr |= new_excepts << 7; return (fesetenv(&fenv) ? -1 : old_excepts); }
void primitive_reset_float_environment(void) { feclearexcept(FE_ALL_EXCEPT); #if defined OPEN_DYLAN_PLATFORM_FREEBSD || defined OPEN_DYLAN_PLATFORM_LINUX feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID); #elif defined OPEN_DYLAN_PLATFORM_DARWIN \ && (defined OPEN_DYLAN_ARCH_X86 || defined OPEN_DYLAN_ARCH_X86_64) fenv_t fenv; fegetenv(&fenv); fenv.__control &= ~(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID); fenv.__mxcsr &= ~((FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID) << 7); fesetenv(&fenv); #endif }
/* * The feholdexcept() function saves the current floating-point environment * in the object pointed to by envp, clears the floating-point status flags, and * then installs a non-stop (continue on floating-point exceptions) mode, if * available, for all floating-point exceptions. */ int feholdexcept(fenv_t *envp) { /* Store the current floating-point environment */ fegetenv(envp); /* Clear exception flags */ _softfloat_float_exception_flags &= ~FE_ALL_EXCEPT; /* Mask all exceptions */ _softfloat_float_exception_mask &= ~FE_ALL_EXCEPT; return (0); }
/* * Test fegetenv() and fesetenv(). * * Prerequisites: fetestexcept(), feclearexcept(), fegetround(), fesetround() */ static void test_fegsetenv(void) { fenv_t env1, env2; int excepts, i; for (i = 0; i < 1 << NEXCEPTS; i++) { excepts = std_except_sets[i]; assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(fegetround() == FE_TONEAREST); assert(fegetenv(&env1) == 0); /* * fe[gs]etenv() should be able to save and restore * exception flags without the spurious inexact * exceptions that afflict raiseexcept(). */ raiseexcept(excepts); if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0 && (excepts & FE_INEXACT) == 0) assert(feclearexcept(FE_INEXACT) == 0); fesetround(FE_DOWNWARD); assert(fegetenv(&env2) == 0); assert(fesetenv(&env1) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(fegetround() == FE_TONEAREST); assert(fesetenv(&env2) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == excepts); assert(fegetround() == FE_DOWNWARD); assert(fesetenv(&env1) == 0); assert(fetestexcept(FE_ALL_EXCEPT) == 0); assert(fegetround() == FE_TONEAREST); } }
static void cache_float_environment (void) { #ifdef HAVE_FEGETENV if (0 != (fegetenv (&scheme_fenv))) error_external_return (); scheme_fenv_p = true; /* Work around glibc lossage: fesetenv has the side effect of masking all exception traps on amd64. */ # ifdef HAVE_FESETENV if (0 != (fesetenv (&scheme_fenv))) error_external_return (); # endif #endif }
static int feenableexcept( unsigned int excepts ) { fenv_t fenv; unsigned int new_excepts = excepts & FE_ALL_EXCEPT, old_excepts; // previous masks if ( fegetenv (&fenv) ) return -1; old_excepts = fenv.__control & FE_ALL_EXCEPT; // unmask fenv.__control &= ~new_excepts; fenv.__mxcsr &= ~(new_excepts << 7); return ( fesetenv (&fenv) ? -1 : old_excepts ); }
void ygl_fpemask(int on) { ygl_valid_fenv = (ygl_valid_fenv || !fegetenv(&ygl_fenv)); if (ygl_valid_fenv) { if (on) { if (on != 1) ygl_depth_fenv = 1; if (ygl_depth_fenv && !--ygl_depth_fenv) fesetenv(&ygl_fenv); } else { if (!ygl_depth_fenv++) fesetenv(FE_DFL_ENV); } } }
TEST(fenv, fegetenv_fesetenv) { // Set FE_OVERFLOW only. feclearexcept(FE_ALL_EXCEPT); ASSERT_EQ(0, fetestexcept(FE_ALL_EXCEPT)); ASSERT_EQ(0, feraiseexcept(FE_OVERFLOW)); // fegetenv (unlike feholdexcept) leaves the current state untouched... fenv_t state; ASSERT_EQ(0, fegetenv(&state)); ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT)); // Dividing by zero sets the appropriate flag... DivideByZero(); ASSERT_EQ(FE_DIVBYZERO | FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT)); // And fesetenv (unlike feupdateenv) clobbers that to return to where // we started. ASSERT_EQ(0, fesetenv(&state)); ASSERT_EQ(FE_OVERFLOW, fetestexcept(FE_ALL_EXCEPT)); }
/* * This tests checks the default FP environment, so it must be first. * The memcmp() test below may be too much to ask for, since there * could be multiple machine-specific default environments. */ static void test_dfl_env(void) { #ifndef NO_STRICT_DFL_ENV fenv_t env; fegetenv(&env); #ifdef __amd64__ /* * Compare the fields that the AMD [1] and Intel [2] specs say will be * set once fnstenv returns. * * Not all amd64 capable processors implement the fnstenv instruction * by zero'ing out the env.__x87.__other field (example: AMD Opteron * 6308). The AMD64/x64 specs aren't explicit on what the * env.__x87.__other field will contain after fnstenv is executed, so * the values in env.__x87.__other could be filled with arbitrary * data depending on how the CPU implements fnstenv. * * 1. http://support.amd.com/TechDocs/26569_APM_v5.pdf * 2. http://www.intel.com/Assets/en_US/PDF/manual/253666.pdf */ assert(memcmp(&env.__mxcsr, &FE_DFL_ENV->__mxcsr, sizeof(env.__mxcsr)) == 0); assert(memcmp(&env.__x87.__control, &FE_DFL_ENV->__x87.__control, sizeof(env.__x87.__control)) == 0); assert(memcmp(&env.__x87.__status, &FE_DFL_ENV->__x87.__status, sizeof(env.__x87.__status)) == 0); assert(memcmp(&env.__x87.__tag, &FE_DFL_ENV->__x87.__tag, sizeof(env.__x87.__tag)) == 0); #else assert(memcmp(&env, FE_DFL_ENV, sizeof(env)) == 0); #endif #endif assert(fetestexcept(FE_ALL_EXCEPT) == 0); }
void SETFEENV() { fenv_t envp; int stat; #ifdef _OPENMP stat = fegetenv(&envp); /* if (fesetenv(&envp) != 0) { perror("Error getting fp env"); } */ #pragma omp parallel shared(envp) { stat = fesetenv(&envp); /* if (fesetenv(&envp) != 0) { perror("Error setting fp env"); } */ } #endif }
longdouble strtold_dm(const char *p,char **endp) { longdouble ldval; int exp; long long msdec,lsdec; unsigned long msscale; char dot,sign; int pow; int ndigits; const char *pinit = p; static char infinity[] = "infinity"; static char nans[] = "nans"; unsigned int old_cw; unsigned int old_status; #if _WIN32 && __DMC__ fenv_t flagp; fegetenv(&flagp); /* Store all exceptions, and current status word */ if (_8087) { // disable exceptions from occurring, set max precision, and round to nearest #if __DMC__ __asm { fstcw word ptr old_cw mov EAX,old_cw mov ECX,EAX and EAX,0xf0c0 or EAX,033fh mov old_cw,EAX fldcw word ptr old_cw mov old_cw,ECX } #else old_cw = _control87(_MCW_EM | _PC_64 | _RC_NEAR, _MCW_EM | _MCW_PC | _MCW_RC); #endif } #endif while (isspace(*p)) p++; sign = 0; /* indicating + */ switch (*p) { case '-': sign++; /* FALL-THROUGH */ case '+': p++; } ldval = 0.0; dot = 0; /* if decimal point has been seen */ exp = 0; msdec = lsdec = 0; msscale = 1; ndigits = 0; #if __DMC__ switch (*p) { case 'i': case 'I': if (memicmp(p,infinity,8) == 0) { p += 8; goto L4; } if (memicmp(p,infinity,3) == 0) /* is it "inf"? */ { p += 3; L4: ldval = HUGE_VAL; goto L3; } break; case 'n': case 'N': if (memicmp(p,nans,4) == 0) /* "nans"? */ { p += 4; ldval = NANS; goto L5; } if (memicmp(p,nans,3) == 0) /* "nan"? */ { p += 3; ldval = NAN; L5: if (*p == '(') /* if (n-char-sequence) */ goto Lerr; /* invalid input */ goto L3; } } #endif if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) { int guard = 0; int anydigits = 0; p += 2; while (1) { int i = *p; while (isxdigit(i)) { anydigits = 1; i = isalpha(i) ? ((i & ~0x20) - ('A' - 10)) : i - '0'; if (ndigits < 16) { msdec = msdec * 16 + i; if (msdec) ndigits++; } else if (ndigits == 16) { while (msdec >= 0) { exp--; msdec <<= 1; i <<= 1; if (i & 0x10) msdec |= 1; } guard = i << 4; ndigits++; exp += 4; } else { guard |= i; exp += 4; } exp -= dot; i = *++p; } #if _WIN32 && __DMC__ if (i == *__locale_decpoint && !dot) #else if (i == '.' && !dot) #endif { p++; dot = 4; } else break; } // Round up if (guard && (sticky || odd)) if (guard & 0x80 && (guard & 0x7F || msdec & 1)) { msdec++; if (msdec == 0) // overflow { msdec = 0x8000000000000000LL; exp++; } } if (anydigits == 0) // if error (no digits seen) goto Lerr; if (*p == 'p' || *p == 'P') { char sexp; int e; sexp = 0; switch (*++p) { case '-': sexp++; case '+': p++; } ndigits = 0; e = 0; while (isdigit(*p)) { if (e < 0x7FFFFFFF / 10 - 10) // prevent integer overflow { e = e * 10 + *p - '0'; } p++; ndigits = 1; } exp += (sexp) ? -e : e; if (!ndigits) // if no digits in exponent goto Lerr; if (msdec) { #if __DMC__ // The 8087 has no instruction to load an // unsigned long long if (msdec < 0) { *(long long *)&ldval = msdec; ((unsigned short *)&ldval)[4] = 0x3FFF + 63; } else { // But does for a signed one __asm { fild qword ptr msdec fstp tbyte ptr ldval } } #else int e2 = 0x3FFF + 63; // left justify mantissa while (msdec >= 0) { msdec <<= 1; e2--; } // Stuff mantissa directly into long double *(long long *)&ldval = msdec; ((unsigned short *)&ldval)[4] = e2; #endif #if 0 if (0) { int i; printf("msdec = x%llx, ldval = %Lg\n", msdec, ldval); for (i = 0; i < 5; i++) printf("%04x ",((unsigned short *)&ldval)[i]); printf("\n"); printf("%llx\n",ldval); } #endif // Exponent is power of 2, not power of 10 #if _WIN32 && __DMC__ __asm { fild dword ptr exp fld tbyte ptr ldval fscale // ST(0) = ST(0) * (2**ST(1)) fstp ST(1) fstp tbyte ptr ldval } #else ldval = ldexpl(ldval,exp); #endif } goto L6; }
Env* rvmStartup(Options* options) { // TODO: Error handling TRACE("Initializing logging"); if (!rvmInitLog(options)) return NULL; #if defined(IOS) && (defined(RVM_ARMV7) || defined(RVM_THUMBV7)) // Enable IEEE-754 denormal support. // Without this the VFP treats numbers that are close to zero as zero itself. // See http://developer.apple.com/library/ios/#technotes/tn2293/_index.html. fenv_t fenv; fegetenv(&fenv); fenv.__fpscr &= ~__fpscr_flush_to_zero; fesetenv(&fenv); #endif // print PID if it was requested if(options->printPID) { pid_t pid = getpid(); if(options->pidFile) { FILE* f = fopen(options->pidFile, "w"); if (!f) return NULL; fprintf(f, "%d", pid); fclose(f); } else { fprintf(stderr, "[DEBUG] %s: pid=%d\n", LOG_TAG, pid); } } // setup the TCP channel socket and wait // for the debugger to connect if(options->enableHooks) { if(!rvmHookSetupTCPChannel(options)) return NULL; if(!rvmHookHandshake(options)) return NULL; } TRACE("Initializing GC"); if (!initGC(options)) return NULL; // Ignore SIGPIPE signals. SIGPIPE interrupts write() calls which we don't // want. Dalvik does this too in dalvikvm/Main.cpp. if (!ignoreSignal(SIGPIPE)) return NULL; // Ignore SIGXFSZ signals. SIGXFSZ is raised when writing beyond the RLIMIT_FSIZE // of the current process (at least on Darwin) using pwrite(). if (!ignoreSignal(SIGXFSZ)) return NULL; VM* vm = rvmCreateVM(options); if (!vm) return NULL; Env* env = rvmCreateEnv(vm); if (!env) return NULL; // TODO: What if we can't allocate Env? if (!initClasspathEntries(env, options->resourcesPath, options->rawBootclasspath, &options->bootclasspath)) return NULL; if (!initClasspathEntries(env, options->resourcesPath, options->rawClasspath, &options->classpath)) return NULL; // Call init on modules TRACE("Initializing classes"); if (!rvmInitClasses(env)) return NULL; TRACE("Initializing memory"); if (!rvmInitMemory(env)) return NULL; TRACE("Initializing methods"); if (!rvmInitMethods(env)) return NULL; TRACE("Initializing strings"); if (!rvmInitStrings(env)) return NULL; TRACE("Initializing monitors"); if (!rvmInitMonitors(env)) return NULL; TRACE("Initializing proxy"); if (!rvmInitProxy(env)) return NULL; TRACE("Initializing threads"); if (!rvmInitThreads(env)) return NULL; TRACE("Initializing attributes"); if (!rvmInitAttributes(env)) return NULL; TRACE("Initializing primitive wrapper classes"); if (!rvmInitPrimitiveWrapperClasses(env)) return NULL; TRACE("Initializing exceptions"); if (!rvmInitExceptions(env)) return NULL; TRACE("Initializing signals"); if (!rvmInitSignals(env)) return NULL; TRACE("Initializing JNI"); if (!rvmInitJNI(env)) return NULL; // Initialize the RoboVM rt JNI code // RT_JNI_OnLoad(&vm->javaVM, NULL); // Initialize the dalvik rt JNI code TRACE("Initializing dalvik's runtime JNI code"); registerCoreLibrariesJni((JNIEnv*) env); #ifdef DARWIN TRACE("Initializing JAR NSURLProtocol"); registerJARURLProtocol(); #endif TRACE("Creating system ClassLoader"); systemClassLoader = rvmGetSystemClassLoader(env); if (rvmExceptionOccurred(env)) goto error_system_ClassLoader; env->currentThread->threadObj->contextClassLoader = systemClassLoader; TRACE("Initialization done"); env->vm->initialized = TRUE; // Start Daemons TRACE("Starting Daemons"); java_lang_Daemons = rvmFindClassUsingLoader(env, "java/lang/Daemons", NULL); if (!java_lang_Daemons) goto error_daemons; java_lang_Daemons_start = rvmGetClassMethod(env, java_lang_Daemons, "start", "()V"); if (!java_lang_Daemons_start) goto error_daemons; rvmCallVoidClassMethod(env, java_lang_Daemons, java_lang_Daemons_start); if (rvmExceptionCheck(env)) goto error_daemons; TRACE("Daemons started"); jboolean errorDuringSetup = FALSE; //If our options has any properties, let's set them before we call our main. if (options->properties) { //First, find java.lang.System, which has the setProperty method. Class* clazz = rvmFindClassUsingLoader(env, "java/lang/System", NULL); if (clazz) { //Get the setProperty method. Method* method = rvmGetClassMethod(env, clazz, "setProperty", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); if (method) { SystemProperty* property = options->properties; //Go through all of our properties and add each one in turn by calling setProperty. while (property != NULL) { Object* key = NULL; Object* value = NULL; //The key is not allowed to be an empty string, so don't set it if we don't get a key. if(property->key && strlen(property->key) > 0) { key = rvmNewStringUTF(env, property->key, -1); } else { FATAL("Cannot have empty key in system property."); errorDuringSetup = TRUE; break; } if (property->value) { value = rvmNewStringUTF(env, property->value, -1); } else { value = rvmNewStringUTF(env, "", -1); } if (key && value) { rvmCallObjectClassMethod(env, clazz, method, key, value); } else { if (!key) { FATALF("Error creating string from system property key: %s", property->key); } if (!value) { FATALF("Error creating string from system property value: %s", property->value); } errorDuringSetup = TRUE; break; } property = property->next; //Advance to the next property. } } } } return (errorDuringSetup) ? NULL : env; error_daemons: error_system_ClassLoader: rvmDetachCurrentThread(env->vm, TRUE, FALSE); return NULL; }
inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) { fegetenv(ctl); }
static __attribute__ ((noinline)) int sse_tests (void) { int ret = 0; fenv_t base_env; if (fegetenv (&base_env) != 0) { puts ("fegetenv (&base_env) failed"); return 1; } if (fesetround (FE_UPWARD) != 0) { puts ("fesetround (FE_UPWARD) failed"); return 1; } if (fesetenv (&base_env) != 0) { puts ("fesetenv (&base_env) failed"); return 1; } volatile float a = 1.0f, b = FLT_MIN, c; c = a + b; if (c != 1.0f) { puts ("fesetenv did not restore rounding mode"); ret = 1; } if (fesetround (FE_DOWNWARD) != 0) { puts ("fesetround (FE_DOWNWARD) failed"); return 1; } if (feupdateenv (&base_env) != 0) { puts ("feupdateenv (&base_env) failed"); return 1; } volatile float d = -FLT_MIN, e; e = a + d; if (e != 1.0f) { puts ("feupdateenv did not restore rounding mode"); ret = 1; } if (fesetround (FE_UPWARD) != 0) { puts ("fesetround (FE_UPWARD) failed"); return 1; } fenv_t upward_env; if (feholdexcept (&upward_env) != 0) { puts ("feholdexcept (&upward_env) failed"); return 1; } if (fesetround (FE_DOWNWARD) != 0) { puts ("fesetround (FE_DOWNWARD) failed"); return 1; } if (fesetenv (&upward_env) != 0) { puts ("fesetenv (&upward_env) failed"); return 1; } e = a + d; if (e != 1.0f) { puts ("fesetenv did not restore rounding mode from feholdexcept"); ret = 1; } if (fesetround (FE_UPWARD) != 0) { puts ("fesetround (FE_UPWARD) failed"); return 1; } if (fesetenv (FE_DFL_ENV) != 0) { puts ("fesetenv (FE_DFL_ENV) failed"); return 1; } c = a + b; if (c != 1.0f) { puts ("fesetenv (FE_DFL_ENV) did not restore rounding mode"); ret = 1; } return ret; }
/* Test that program aborts with no masked interrupts */ static void feenv_nomask_test (const char *flag_name, int fe_exc) { #if defined FE_NOMASK_ENV int status; pid_t pid; fenv_t saved; fegetenv (&saved); errno = 0; fesetenv (FE_NOMASK_ENV); status = errno; fesetenv (&saved); if (status == ENOSYS) { printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n"); return; } printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n"); printf (" when feraiseexcept (%s) is called.\n", flag_name); pid = fork (); if (pid == 0) { #ifdef RLIMIT_CORE /* Try to avoid dumping core. */ struct rlimit core_limit; core_limit.rlim_cur = 0; core_limit.rlim_max = 0; setrlimit (RLIMIT_CORE, &core_limit); #endif fesetenv (FE_NOMASK_ENV); feraiseexcept (fe_exc); exit (2); } else if (pid < 0) { if (errno != ENOSYS) { printf (" Fail: Could not fork.\n"); ++count_errors; } else printf (" `fork' not implemented, test ignored.\n"); } else { if (waitpid (pid, &status, 0) != pid) { printf (" Fail: waitpid call failed.\n"); ++count_errors; } else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE) printf (" Pass: Process received SIGFPE.\n"); else { printf (" Fail: Process didn't receive signal and exited with status %d.\n", status); ++count_errors; } } #endif }
int feholdexcept96(fenv_t *p) { (void) fegetenv(p); (void) feclearexcept(FE_ALL_EXCEPT); return fex_set_handling(FEX_ALL, FEX_NONSTOP, NULL); }
Env* rvmStartup(Options* options) { // TODO: Error handling #if defined(IOS) && (defined(RVM_ARMV7) || defined(RVM_THUMBV7)) // Enable IEEE-754 denormal support. // Without this the VFP treats numbers that are close to zero as zero itself. // See http://developer.apple.com/library/ios/#technotes/tn2293/_index.html. fenv_t fenv; fegetenv(&fenv); fenv.__fpscr &= ~__fpscr_flush_to_zero; fesetenv(&fenv); #endif TRACE("Initializing GC"); if (!initGC(options)) return NULL; // Ignore SIGPIPE signals. SIGPIPE interrupts write() calls which we don't // want. Dalvik does this too in dalvikvm/Main.cpp. if (!ignoreSignal(SIGPIPE)) return NULL; // Ignore SIGXFSZ signals. SIGXFSZ is raised when writing beyond the RLIMIT_FSIZE // of the current process (at least on Darwin) using pwrite(). if (!ignoreSignal(SIGXFSZ)) return NULL; VM* vm = rvmCreateVM(options); if (!vm) return NULL; Env* env = rvmCreateEnv(vm); if (!env) return NULL; // TODO: What if we can't allocate Env? if (!initClasspathEntries(env, options->basePath, options->rawBootclasspath, &options->bootclasspath)) return NULL; if (!initClasspathEntries(env, options->basePath, options->rawClasspath, &options->classpath)) return NULL; // Call init on modules TRACE("Initializing logging"); if (!rvmInitLog(env)) return NULL; TRACE("Initializing classes"); if (!rvmInitClasses(env)) return NULL; TRACE("Initializing memory"); if (!rvmInitMemory(env)) return NULL; TRACE("Initializing methods"); if (!rvmInitMethods(env)) return NULL; TRACE("Initializing strings"); if (!rvmInitStrings(env)) return NULL; TRACE("Initializing monitors"); if (!rvmInitMonitors(env)) return NULL; TRACE("Initializing proxy"); if (!rvmInitProxy(env)) return NULL; TRACE("Initializing threads"); if (!rvmInitThreads(env)) return NULL; TRACE("Initializing attributes"); if (!rvmInitAttributes(env)) return NULL; TRACE("Initializing primitive wrapper classes"); if (!rvmInitPrimitiveWrapperClasses(env)) return NULL; TRACE("Initializing exceptions"); if (!rvmInitExceptions(env)) return NULL; TRACE("Initializing signals"); if (!rvmInitSignals(env)) return NULL; // Initialize the RoboVM rt JNI code // RT_JNI_OnLoad(&vm->javaVM, NULL); // Initialize the dalvik rt JNI code TRACE("Initializing dalvik's runtime JNI code"); registerCoreLibrariesJni((JNIEnv*) env); TRACE("Creating system ClassLoader"); systemClassLoader = rvmGetSystemClassLoader(env); if (rvmExceptionOccurred(env)) goto error_system_ClassLoader; env->currentThread->threadObj->contextClassLoader = systemClassLoader; TRACE("Initialization done"); env->vm->initialized = TRUE; // Start Daemons TRACE("Starting Daemons"); java_lang_Daemons = rvmFindClassUsingLoader(env, "java/lang/Daemons", NULL); if (!java_lang_Daemons) goto error_daemons; java_lang_Daemons_start = rvmGetClassMethod(env, java_lang_Daemons, "start", "()V"); if (!java_lang_Daemons_start) goto error_daemons; rvmCallVoidClassMethod(env, java_lang_Daemons, java_lang_Daemons_start); if (rvmExceptionCheck(env)) goto error_daemons; TRACE("Daemons started"); return env; error_daemons: error_system_ClassLoader: rvmDetachCurrentThread(env->vm, TRUE, FALSE); return NULL; }