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) { 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 + "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', 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)); 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 class Global
{ {
public: public:
enum Which { Variable, Function, FuncPtrTable, FFI, ArrayView, MathBuiltin, Constant }; enum Which {
Variable,
ConstantLiteral,
ConstantImport,
Function,
FuncPtrTable,
FFI,
ArrayView,
MathBuiltin
};
private: private:
Which which_; Which which_;
union { union {
struct { struct {
uint32_t index_;
VarType::Which type_; VarType::Which type_;
bool isConst_; uint32_t index_;
bool isLitConst_; Value literalValue_;
Value litConstValue_; } varOrConst;
} var;
uint32_t funcIndex_; uint32_t funcIndex_;
uint32_t funcPtrTableIndex_; uint32_t funcPtrTableIndex_;
uint32_t ffiIndex_; uint32_t ffiIndex_;
ArrayBufferView::ViewType viewType_; ArrayBufferView::ViewType viewType_;
AsmJSMathBuiltin mathBuiltin_; AsmJSMathBuiltin mathBuiltin_;
double constant_;
} u; } u;
friend class ModuleCompiler; friend class ModuleCompiler;
@ -957,26 +963,20 @@ class MOZ_STACK_CLASS ModuleCompiler
Which which() const { Which which() const {
return which_; return which_;
} }
VarType varType() const { VarType varOrConstType() const {
JS_ASSERT(which_ == Variable); JS_ASSERT(which_ == Variable || which_ == ConstantLiteral || which_ == ConstantImport);
return VarType(u.var.type_); return VarType(u.varOrConst.type_);
} }
uint32_t varIndex() const { uint32_t varOrConstIndex() const {
JS_ASSERT(which_ == Variable); JS_ASSERT(which_ == Variable || which_ == ConstantImport);
return u.var.index_; return u.varOrConst.index_;
} }
bool varIsConstant() const { bool isConst() const {
JS_ASSERT(which_ == Variable); return which_ == ConstantLiteral || which_ == ConstantImport;
return u.var.isConst_;
} }
bool varIsLitConstant() const { Value constLiteralValue() const {
JS_ASSERT(which_ == Variable); JS_ASSERT(which_ == ConstantLiteral);
return u.var.isLitConst_; return u.varOrConst.literalValue_;
}
const Value &litConstValue() const {
JS_ASSERT(which_ == Variable);
JS_ASSERT(u.var.isLitConst_);
return u.var.litConstValue_;
} }
uint32_t funcIndex() const { uint32_t funcIndex() const {
JS_ASSERT(which_ == Function); JS_ASSERT(which_ == Function);
@ -998,10 +998,6 @@ class MOZ_STACK_CLASS ModuleCompiler
JS_ASSERT(which_ == MathBuiltin); JS_ASSERT(which_ == MathBuiltin);
return u.mathBuiltin_; return u.mathBuiltin_;
} }
double constant() const {
JS_ASSERT(which_ == Constant);
return u.constant_;
}
}; };
typedef js::Vector<const Func*> FuncPtrVector; typedef js::Vector<const Func*> FuncPtrVector;
@ -1312,20 +1308,20 @@ class MOZ_STACK_CLASS ModuleCompiler
void initImportArgumentName(PropertyName *n) { module_->initImportArgumentName(n); } void initImportArgumentName(PropertyName *n) { module_->initImportArgumentName(n); }
void initBufferArgumentName(PropertyName *n) { module_->initBufferArgumentName(n); } void initBufferArgumentName(PropertyName *n) { module_->initBufferArgumentName(n); }
bool addGlobalVarInitConstant(PropertyName *varName, VarType type, const Value &v, bool addGlobalVarInit(PropertyName *varName, VarType type, const Value &v, bool isConst) {
bool isConst) {
uint32_t index; uint32_t index;
if (!module_->addGlobalVarInitConstant(v, type.toCoercion(), &index)) if (!module_->addGlobalVarInit(v, type.toCoercion(), &index))
return false; 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) if (!global)
return false; return false;
global->u.var.index_ = index; global->u.varOrConst.index_ = index;
global->u.var.type_ = type.which(); global->u.varOrConst.type_ = type.which();
global->u.var.isConst_ = isConst;
global->u.var.isLitConst_ = isConst;
if (isConst) if (isConst)
global->u.var.litConstValue_ = v; global->u.varOrConst.literalValue_ = v;
return globals_.putNew(varName, global); return globals_.putNew(varName, global);
} }
bool addGlobalVarImport(PropertyName *varName, PropertyName *fieldName, AsmJSCoercion coercion, bool addGlobalVarImport(PropertyName *varName, PropertyName *fieldName, AsmJSCoercion coercion,
@ -1333,13 +1329,14 @@ class MOZ_STACK_CLASS ModuleCompiler
uint32_t index; uint32_t index;
if (!module_->addGlobalVarImport(fieldName, coercion, &index)) if (!module_->addGlobalVarImport(fieldName, coercion, &index))
return false; 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) if (!global)
return false; return false;
global->u.var.index_ = index; global->u.varOrConst.index_ = index;
global->u.var.type_ = VarType(coercion).which(); global->u.varOrConst.type_ = VarType(coercion).which();
global->u.var.isConst_ = isConst;
global->u.var.isLitConst_ = false;
return globals_.putNew(varName, global); return globals_.putNew(varName, global);
} }
bool addFunction(PropertyName *name, Signature &&sig, Func **func) { 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) { bool addGlobalConstant(PropertyName *varName, double constant, PropertyName *fieldName) {
if (!module_->addGlobalConstant(constant, fieldName)) if (!module_->addGlobalConstant(constant, fieldName))
return false; return false;
Global *global = moduleLifo_.new_<Global>(Global::Constant); Global *global = moduleLifo_.new_<Global>(Global::ConstantLiteral);
if (!global) if (!global)
return false; return false;
global->u.constant_ = constant; global->u.varOrConst.literalValue_ = DoubleValue(constant);
global->u.varOrConst.type_ = VarType::Double;
return globals_.putNew(varName, global); return globals_.putNew(varName, global);
} }
bool addExportedFunction(const Func *func, PropertyName *maybeFieldName) { bool addExportedFunction(const Func *func, PropertyName *maybeFieldName) {
@ -2253,16 +2251,12 @@ class FunctionCompiler
{ {
if (!curBlock_) if (!curBlock_)
return nullptr; return nullptr;
if (global.varIsLitConstant()) {
JS_ASSERT(global.litConstValue().isNumber()); uint32_t index = global.varOrConstIndex();
MConstant *constant = MConstant::New(alloc(), global.litConstValue()); unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(index);
curBlock_->add(constant); MIRType type = global.varOrConstType().toMIRType();
return constant;
}
MIRType type = global.varType().toMIRType();
unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varIndex());
MAsmJSLoadGlobalVar *load = MAsmJSLoadGlobalVar::New(alloc(), type, globalDataOffset, MAsmJSLoadGlobalVar *load = MAsmJSLoadGlobalVar::New(alloc(), type, globalDataOffset,
global.varIsConstant()); global.isConst());
curBlock_->add(load); curBlock_->add(load);
return load; return load;
} }
@ -2271,7 +2265,8 @@ class FunctionCompiler
{ {
if (!curBlock_) if (!curBlock_)
return; return;
unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varIndex()); JS_ASSERT(!global.isConst());
unsigned globalDataOffset = module().globalVarIndexToGlobalDataOffset(global.varOrConstIndex());
curBlock_->add(MAsmJSStoreGlobalVar::New(alloc(), globalDataOffset, v)); curBlock_->add(MAsmJSStoreGlobalVar::New(alloc(), globalDataOffset, v));
} }
@ -2981,7 +2976,7 @@ CheckGlobalVariableInitConstant(ModuleCompiler &m, PropertyName *varName, ParseN
if (!literal.hasType()) if (!literal.hasType())
return m.fail(initNode, "global initializer is out of representable integer range"); 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 static bool
@ -3349,13 +3344,14 @@ CheckVarRef(FunctionCompiler &f, ParseNode *varRef, MDefinition **def, Type *typ
if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) { if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) {
switch (global->which()) { switch (global->which()) {
case ModuleCompiler::Global::Constant: case ModuleCompiler::Global::ConstantLiteral:
*def = f.constant(DoubleValue(global->constant()), Type::Double); *def = f.constant(global->constLiteralValue(), global->varOrConstType().toType());
*type = Type::Double; *type = global->varOrConstType().toType();
break; break;
case ModuleCompiler::Global::ConstantImport:
case ModuleCompiler::Global::Variable: case ModuleCompiler::Global::Variable:
*def = f.loadGlobalVar(*global); *def = f.loadGlobalVar(*global);
*type = global->varType().toType(); *type = global->varOrConstType().toType();
break; break;
case ModuleCompiler::Global::Function: case ModuleCompiler::Global::Function:
case ModuleCompiler::Global::FFI: case ModuleCompiler::Global::FFI:
@ -3381,14 +3377,10 @@ IsLiteralOrConstInt(FunctionCompiler &f, ParseNode *pn, uint32_t *u32)
PropertyName *name = pn->name(); PropertyName *name = pn->name();
const ModuleCompiler::Global *global = f.lookupGlobal(name); const ModuleCompiler::Global *global = f.lookupGlobal(name);
if (!global || if (!global || global->which() != ModuleCompiler::Global::ConstantLiteral)
global->which() != ModuleCompiler::Global::Variable ||
!global->varIsLitConstant())
{
return false; return false;
}
const Value &v = global->litConstValue(); const Value &v = global->constLiteralValue();
if (!v.isInt32()) if (!v.isInt32())
return false; return false;
@ -3602,11 +3594,9 @@ CheckAssignName(FunctionCompiler &f, ParseNode *lhs, ParseNode *rhs, MDefinition
} else if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) { } else if (const ModuleCompiler::Global *global = f.lookupGlobal(name)) {
if (global->which() != ModuleCompiler::Global::Variable) if (global->which() != ModuleCompiler::Global::Variable)
return f.failName(lhs, "'%s' is not a mutable variable", name); return f.failName(lhs, "'%s' is not a mutable variable", name);
if (global->varIsConstant()) if (!(rhsType <= global->varOrConstType())) {
return f.failName(lhs, "'%s' is a constant variable and not mutable", name);
if (!(rhsType <= global->varType())) {
return f.failf(lhs, "%s is not a subtype of %s", 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); f.storeGlobalVar(*global, rhsDef);
} else { } else {
@ -4089,7 +4079,8 @@ CheckCall(FunctionCompiler &f, ParseNode *call, RetType retType, MDefinition **d
return CheckFFICall(f, call, global->ffiIndex(), retType, def, type); return CheckFFICall(f, call, global->ffiIndex(), retType, def, type);
case ModuleCompiler::Global::MathBuiltin: case ModuleCompiler::Global::MathBuiltin:
return CheckMathBuiltinCall(f, call, global->mathBuiltin(), retType, def, type); 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::Variable:
case ModuleCompiler::Global::FuncPtrTable: case ModuleCompiler::Global::FuncPtrTable:
case ModuleCompiler::Global::ArrayView: case ModuleCompiler::Global::ArrayView:

View File

@ -456,7 +456,7 @@ class AsmJSModule
return charsBegin_ + pod.charsLength_; 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); JS_ASSERT(pod.funcPtrTableAndExitBytes_ == 0);
if (pod.numGlobalVars_ == UINT32_MAX) if (pod.numGlobalVars_ == UINT32_MAX)
return false; return false;