Bug 952306: Refactor Variable into Variable, ConstantImport and ConstantLiteral in Odin; r=luke

This commit is contained in:
Benjamin Bouvier 2014-01-29 14:27:00 +01:00
parent 318161305a
commit cc29413fe5
3 changed files with 63 additions and 71 deletions

View File

@ -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));
}

View File

@ -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<const Func*> 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>(Global::Variable);
Global::Which which = isConst ? Global::ConstantLiteral : Global::Variable;
Global *global = moduleLifo_.new_<Global>(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>(Global::Variable);
Global::Which which = isConst ? Global::ConstantImport : Global::Variable;
Global *global = moduleLifo_.new_<Global>(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>(Global::Constant);
Global *global = moduleLifo_.new_<Global>(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:

View File

@ -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;