diff --git a/js/src/jit-test/tests/asm.js/testFloat32.js b/js/src/jit-test/tests/asm.js/testFloat32.js index 4b78b4c9e5c..cda21944e6c 100644 --- a/js/src/jit-test/tests/asm.js/testFloat32.js +++ b/js/src/jit-test/tests/asm.js/testFloat32.js @@ -107,6 +107,7 @@ specials = [NaN, Infinity] for (v of values) { assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var x = toF(" + v + "); function f() {return toF(x);} return f"), this)(), Math.fround(v)); + assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "const x = toF(" + v + "); function f() {return toF(x);} return f"), this)(), Math.fround(v)); assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "var x = toF(0.); function f() {x = toF(" + v + "); return toF(x);} return f"), this)(), Math.fround(v)); assertEq(asmLink(asmCompile('glob', 'ffi', USE_ASM + TO_FLOAT32 + "var x = toF(ffi.x); function f() {return toF(x);} return f"), this, {x:v})(), Math.fround(v)); } diff --git a/js/src/jit/AsmJS.cpp b/js/src/jit/AsmJS.cpp index bcddc1cccaa..983ce177bd9 100644 --- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -928,24 +928,30 @@ class MOZ_STACK_CLASS ModuleCompiler class Global { public: - enum Which { Variable, Function, FuncPtrTable, FFI, ArrayView, MathBuiltin, Constant }; + enum Which { + Variable, + ConstantLiteral, + ConstantImport, + Function, + FuncPtrTable, + FFI, + ArrayView, + MathBuiltin + }; private: Which which_; union { struct { - uint32_t index_; VarType::Which type_; - bool isConst_; - bool isLitConst_; - Value litConstValue_; - } var; + uint32_t index_; + Value literalValue_; + } varOrConst; uint32_t funcIndex_; uint32_t funcPtrTableIndex_; uint32_t ffiIndex_; ArrayBufferView::ViewType viewType_; AsmJSMathBuiltin mathBuiltin_; - double constant_; } u; friend class ModuleCompiler; @@ -957,26 +963,20 @@ class MOZ_STACK_CLASS ModuleCompiler Which which() const { return which_; } - VarType varType() const { - JS_ASSERT(which_ == Variable); - return VarType(u.var.type_); + VarType varOrConstType() const { + JS_ASSERT(which_ == Variable || which_ == ConstantLiteral || which_ == ConstantImport); + return VarType(u.varOrConst.type_); } - uint32_t varIndex() const { - JS_ASSERT(which_ == Variable); - return u.var.index_; + uint32_t varOrConstIndex() const { + JS_ASSERT(which_ == Variable || which_ == ConstantImport); + return u.varOrConst.index_; } - bool varIsConstant() const { - JS_ASSERT(which_ == Variable); - return u.var.isConst_; + bool isConst() const { + return which_ == ConstantLiteral || which_ == ConstantImport; } - bool varIsLitConstant() const { - JS_ASSERT(which_ == Variable); - return u.var.isLitConst_; - } - const Value &litConstValue() const { - JS_ASSERT(which_ == Variable); - JS_ASSERT(u.var.isLitConst_); - return u.var.litConstValue_; + Value constLiteralValue() const { + JS_ASSERT(which_ == ConstantLiteral); + return u.varOrConst.literalValue_; } uint32_t funcIndex() const { JS_ASSERT(which_ == Function); @@ -998,10 +998,6 @@ class MOZ_STACK_CLASS ModuleCompiler JS_ASSERT(which_ == MathBuiltin); return u.mathBuiltin_; } - double constant() const { - JS_ASSERT(which_ == Constant); - return u.constant_; - } }; typedef js::Vector FuncPtrVector; @@ -1312,20 +1308,20 @@ class MOZ_STACK_CLASS ModuleCompiler void initImportArgumentName(PropertyName *n) { module_->initImportArgumentName(n); } void initBufferArgumentName(PropertyName *n) { module_->initBufferArgumentName(n); } - bool addGlobalVarInitConstant(PropertyName *varName, VarType type, const Value &v, - bool isConst) { + bool addGlobalVarInit(PropertyName *varName, VarType type, const Value &v, bool isConst) { uint32_t index; - if (!module_->addGlobalVarInitConstant(v, type.toCoercion(), &index)) + if (!module_->addGlobalVarInit(v, type.toCoercion(), &index)) return false; - Global *global = moduleLifo_.new_(Global::Variable); + + Global::Which which = isConst ? Global::ConstantLiteral : Global::Variable; + Global *global = moduleLifo_.new_(which); if (!global) return false; - global->u.var.index_ = index; - global->u.var.type_ = type.which(); - global->u.var.isConst_ = isConst; - global->u.var.isLitConst_ = isConst; + global->u.varOrConst.index_ = index; + global->u.varOrConst.type_ = type.which(); if (isConst) - global->u.var.litConstValue_ = v; + global->u.varOrConst.literalValue_ = v; + return globals_.putNew(varName, global); } bool addGlobalVarImport(PropertyName *varName, PropertyName *fieldName, AsmJSCoercion coercion, @@ -1333,13 +1329,14 @@ class MOZ_STACK_CLASS ModuleCompiler uint32_t index; if (!module_->addGlobalVarImport(fieldName, coercion, &index)) return false; - Global *global = moduleLifo_.new_(Global::Variable); + + Global::Which which = isConst ? Global::ConstantImport : Global::Variable; + Global *global = moduleLifo_.new_(which); if (!global) return false; - global->u.var.index_ = index; - global->u.var.type_ = VarType(coercion).which(); - global->u.var.isConst_ = isConst; - global->u.var.isLitConst_ = false; + global->u.varOrConst.index_ = index; + global->u.varOrConst.type_ = VarType(coercion).which(); + return globals_.putNew(varName, global); } bool addFunction(PropertyName *name, Signature &&sig, Func **func) { @@ -1405,10 +1402,11 @@ class MOZ_STACK_CLASS ModuleCompiler bool addGlobalConstant(PropertyName *varName, double constant, PropertyName *fieldName) { if (!module_->addGlobalConstant(constant, fieldName)) return false; - Global *global = moduleLifo_.new_(Global::Constant); + Global *global = moduleLifo_.new_(Global::ConstantLiteral); if (!global) return false; - global->u.constant_ = constant; + global->u.varOrConst.literalValue_ = DoubleValue(constant); + global->u.varOrConst.type_ = VarType::Double; return globals_.putNew(varName, global); } bool addExportedFunction(const Func *func, PropertyName *maybeFieldName) { @@ -2253,16 +2251,12 @@ class FunctionCompiler { if (!curBlock_) return nullptr; - if (global.varIsLitConstant()) { - JS_ASSERT(global.litConstValue().isNumber()); - MConstant *constant = MConstant::New(alloc(), global.litConstValue()); - curBlock_->add(constant); - return constant; - } - MIRType type = global.varType().toMIRType(); - unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varIndex()); + + uint32_t index = global.varOrConstIndex(); + unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(index); + MIRType type = global.varOrConstType().toMIRType(); MAsmJSLoadGlobalVar *load = MAsmJSLoadGlobalVar::New(alloc(), type, globalDataOffset, - global.varIsConstant()); + global.isConst()); curBlock_->add(load); return load; } @@ -2271,7 +2265,8 @@ class FunctionCompiler { if (!curBlock_) return; - unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varIndex()); + JS_ASSERT(!global.isConst()); + unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varOrConstIndex()); curBlock_->add(MAsmJSStoreGlobalVar::New(alloc(), globalDataOffset, v)); } @@ -2981,7 +2976,7 @@ CheckGlobalVariableInitConstant(ModuleCompiler &m, PropertyName *varName, ParseN if (!literal.hasType()) return m.fail(initNode, "global initializer is out of representable integer range"); - return m.addGlobalVarInitConstant(varName, literal.varType(), literal.value(), isConst); + return m.addGlobalVarInit(varName, literal.varType(), literal.value(), isConst); } static bool @@ -3349,13 +3344,14 @@ CheckVarRef(FunctionCompiler &f, ParseNode *varRef, MDefinition **def, Type *typ if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) { switch (global->which()) { - case ModuleCompiler::Global::Constant: - *def = f.constant(DoubleValue(global->constant()), Type::Double); - *type = Type::Double; + case ModuleCompiler::Global::ConstantLiteral: + *def = f.constant(global->constLiteralValue(), global->varOrConstType().toType()); + *type = global->varOrConstType().toType(); break; + case ModuleCompiler::Global::ConstantImport: case ModuleCompiler::Global::Variable: *def = f.loadGlobalVar(*global); - *type = global->varType().toType(); + *type = global->varOrConstType().toType(); break; case ModuleCompiler::Global::Function: case ModuleCompiler::Global::FFI: @@ -3381,14 +3377,10 @@ IsLiteralOrConstInt(FunctionCompiler &f, ParseNode *pn, uint32_t *u32) PropertyName *name = pn->name(); const ModuleCompiler::Global *global = f.lookupGlobal(name); - if (!global || - global->which() != ModuleCompiler::Global::Variable || - !global->varIsLitConstant()) - { + if (!global || global->which() != ModuleCompiler::Global::ConstantLiteral) return false; - } - const Value &v = global->litConstValue(); + const Value &v = global->constLiteralValue(); if (!v.isInt32()) return false; @@ -3602,11 +3594,9 @@ CheckAssignName(FunctionCompiler &f, ParseNode *lhs, ParseNode *rhs, MDefinition } else if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) { if (global->which() != ModuleCompiler::Global::Variable) return f.failName(lhs, "'%s' is not a mutable variable", name); - if (global->varIsConstant()) - return f.failName(lhs, "'%s' is a constant variable and not mutable", name); - if (!(rhsType <= global->varType())) { + if (!(rhsType <= global->varOrConstType())) { return f.failf(lhs, "%s is not a subtype of %s", - rhsType.toChars(), global->varType().toType().toChars()); + rhsType.toChars(), global->varOrConstType().toType().toChars()); } f.storeGlobalVar(*global, rhsDef); } else { @@ -4089,7 +4079,8 @@ CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **d return CheckFFICall(f, call, global->ffiIndex(), retType, def, type); case ModuleCompiler::Global::MathBuiltin: return CheckMathBuiltinCall(f, call, global->mathBuiltin(), retType, def, type); - case ModuleCompiler::Global::Constant: + case ModuleCompiler::Global::ConstantLiteral: + case ModuleCompiler::Global::ConstantImport: case ModuleCompiler::Global::Variable: case ModuleCompiler::Global::FuncPtrTable: case ModuleCompiler::Global::ArrayView: diff --git a/js/src/jit/AsmJSModule.h b/js/src/jit/AsmJSModule.h index bee8a195eaa..207baed4d8a 100644 --- a/js/src/jit/AsmJSModule.h +++ b/js/src/jit/AsmJSModule.h @@ -456,7 +456,7 @@ class AsmJSModule return charsBegin_ + pod.charsLength_; } - bool addGlobalVarInitConstant(const Value &v, AsmJSCoercion coercion, uint32_t *globalIndex) { + bool addGlobalVarInit(const Value &v, AsmJSCoercion coercion, uint32_t *globalIndex) { JS_ASSERT(pod.funcPtrTableAndExitBytes_ == 0); if (pod.numGlobalVars_ == UINT32_MAX) return false;