static bool GetGlobalExport(JSContext* cx, const GlobalDescVector& globals, uint32_t globalIndex, const ValVector& globalImports, MutableHandleValue jsval) { const GlobalDesc& global = globals[globalIndex]; // Imports are located upfront in the globals array. Val val; switch (global.kind()) { case GlobalKind::Import: val = globalImports[globalIndex]; break; case GlobalKind::Variable: MOZ_CRASH("mutable variables can't be exported"); case GlobalKind::Constant: val = global.constantValue(); break; } switch (global.type()) { case ValType::I32: { jsval.set(Int32Value(val.i32())); return true; } case ValType::I64: { MOZ_ASSERT(JitOptions.wasmTestMode, "no int64 in asm.js/wasm"); RootedObject obj(cx, CreateI64Object(cx, val.i64())); if (!obj) return false; jsval.set(ObjectValue(*obj)); return true; } case ValType::F32: { float f = val.f32(); if (JitOptions.wasmTestMode && IsNaN(f)) { RootedObject obj(cx, CreateCustomNaNObject(cx, &f)); if (!obj) return false; jsval.set(ObjectValue(*obj)); return true; } jsval.set(DoubleValue(double(f))); return true; } case ValType::F64: { double d = val.f64(); if (JitOptions.wasmTestMode && IsNaN(d)) { RootedObject obj(cx, CreateCustomNaNObject(cx, &d)); if (!obj) return false; jsval.set(ObjectValue(*obj)); return true; } jsval.set(DoubleValue(d)); return true; } default: { break; } } MOZ_CRASH("unexpected type when creating global exports"); }
bool DebugState::getGlobal(Instance& instance, uint32_t globalIndex, MutableHandleValue vp) { const GlobalDesc& global = metadata().globals[globalIndex]; if (global.isConstant()) { Val value = global.constantValue(); switch (value.type()) { case ValType::I32: vp.set(Int32Value(value.i32())); break; case ValType::I64: // Just display as a Number; it's ok if we lose some precision vp.set(NumberValue((double)value.i64())); break; case ValType::F32: vp.set(NumberValue(JS::CanonicalizeNaN(value.f32()))); break; case ValType::F64: vp.set(NumberValue(JS::CanonicalizeNaN(value.f64()))); break; default: MOZ_CRASH("Global constant type"); } return true; } uint8_t* globalData = instance.globalData(); void* dataPtr = globalData + global.offset(); switch (global.type()) { case ValType::I32: { vp.set(Int32Value(*static_cast<int32_t*>(dataPtr))); break; } case ValType::I64: { // Just display as a Number; it's ok if we lose some precision vp.set(NumberValue((double)*static_cast<int64_t*>(dataPtr))); break; } case ValType::F32: { vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<float*>(dataPtr)))); break; } case ValType::F64: { vp.set(NumberValue(JS::CanonicalizeNaN(*static_cast<double*>(dataPtr)))); break; } default: MOZ_CRASH("Global variable type"); break; } return true; }
static bool ValidateGlobalVariable(JSContext* cx, const AsmJSModule& module, AsmJSModule::Global& global, HandleValue importVal) { void* datum = module.globalData() + global.varGlobalDataOffset(); switch (global.varInitKind()) { case AsmJSModule::Global::InitConstant: { Val v = global.varInitVal(); switch (v.type()) { case ValType::I32: *(int32_t*)datum = v.i32(); break; case ValType::I64: MOZ_CRASH("int64"); case ValType::F32: *(float*)datum = v.f32(); break; case ValType::F64: *(double*)datum = v.f64(); break; case ValType::I32x4: memcpy(datum, v.i32x4(), Simd128DataSize); break; case ValType::F32x4: memcpy(datum, v.f32x4(), Simd128DataSize); break; } break; } case AsmJSModule::Global::InitImport: { RootedPropertyName field(cx, global.varImportField()); RootedValue v(cx); if (!GetDataProperty(cx, importVal, field, &v)) return false; if (!v.isPrimitive() && !HasPureCoercion(cx, v)) return LinkFail(cx, "Imported values must be primitives"); switch (global.varInitImportType()) { case ValType::I32: if (!ToInt32(cx, v, (int32_t*)datum)) return false; break; case ValType::I64: MOZ_CRASH("int64"); case ValType::F32: if (!RoundFloat32(cx, v, (float*)datum)) return false; break; case ValType::F64: if (!ToNumber(cx, v, (double*)datum)) return false; break; case ValType::I32x4: { SimdConstant simdConstant; if (!ToSimdConstant<Int32x4>(cx, v, &simdConstant)) return false; memcpy(datum, simdConstant.asInt32x4(), Simd128DataSize); break; } case ValType::F32x4: { SimdConstant simdConstant; if (!ToSimdConstant<Float32x4>(cx, v, &simdConstant)) return false; memcpy(datum, simdConstant.asFloat32x4(), Simd128DataSize); break; } } break; } } return true; }