mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Some parts of x@<name> working.
This commit is contained in:
parent
5cefdedddb
commit
087d2475a7
@ -10,6 +10,7 @@
|
||||
BRANCH_FALSE, /* target label, condition */
|
||||
BRANCH_TRUE, /* target label, condition */
|
||||
CALL, /* result, target, name, args */
|
||||
CAST, /* dest, rvalue, toType */
|
||||
COMPARE_EQ, /* dest, source1, source2 */
|
||||
COMPARE_GE, /* dest, source1, source2 */
|
||||
COMPARE_GT, /* dest, source1, source2 */
|
||||
@ -158,6 +159,22 @@
|
||||
}
|
||||
};
|
||||
|
||||
class Cast : public Instruction_3<TypedRegister, TypedRegister, JSType*> {
|
||||
public:
|
||||
/* dest, rvalue, toType */
|
||||
Cast (TypedRegister aOp1, TypedRegister aOp2, JSType* aOp3) :
|
||||
Instruction_3<TypedRegister, TypedRegister, JSType*>
|
||||
(CAST, aOp1, aOp2, aOp3) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[CAST] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'";
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
class CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* dest, source1, source2 */
|
||||
@ -550,11 +567,11 @@
|
||||
}
|
||||
};
|
||||
|
||||
class NewFunction : public Instruction_2<TypedRegister, ICodeModule *> {
|
||||
class NewFunction : public Instruction_2<TypedRegister, ICodeModule*> {
|
||||
public:
|
||||
/* dest, ICodeModule */
|
||||
NewFunction (TypedRegister aOp1, ICodeModule * aOp2) :
|
||||
Instruction_2<TypedRegister, ICodeModule *>
|
||||
NewFunction (TypedRegister aOp1, ICodeModule* aOp2) :
|
||||
Instruction_2<TypedRegister, ICodeModule*>
|
||||
(NEW_FUNCTION, aOp1, aOp2) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[NEW_FUNCTION] << "\t" << "R" << mOp1.first << ", " << "ICodeModule";
|
||||
@ -1035,6 +1052,7 @@
|
||||
"BRANCH_FALSE ",
|
||||
"BRANCH_TRUE ",
|
||||
"CALL ",
|
||||
"CAST ",
|
||||
"COMPARE_EQ ",
|
||||
"COMPARE_GE ",
|
||||
"COMPARE_GT ",
|
||||
|
@ -482,6 +482,14 @@ TypedRegister ICodeGenerator::super()
|
||||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::cast(TypedRegister arg, JSType *toType)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), toType);
|
||||
Cast *instr = new Cast(dest, arg, toType);
|
||||
iCode->push_back(instr);
|
||||
return dest;
|
||||
}
|
||||
|
||||
void ICodeGenerator::branch(Label *label)
|
||||
{
|
||||
Branch *instr = new Branch(label);
|
||||
@ -1216,17 +1224,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
ret = genExpr(b->op2);
|
||||
if (b->op1->getKind() == ExprNode::identifier) {
|
||||
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
|
||||
/*
|
||||
if (!isWithinWith()) {
|
||||
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
if (v.first != NotARegister)
|
||||
move(v, ret);
|
||||
else
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
}
|
||||
else
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
*/
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::dot) {
|
||||
@ -1259,27 +1256,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
ret = genExpr(b->op2);
|
||||
if (b->op1->getKind() == ExprNode::identifier) {
|
||||
|
||||
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
|
||||
/*
|
||||
if (!isWithinWith()) {
|
||||
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
if (v.first != NotARegister) {
|
||||
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
move(v, ret);
|
||||
}
|
||||
else {
|
||||
v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TypedRegister v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::dot) {
|
||||
@ -1463,6 +1440,31 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
break;
|
||||
|
||||
case ExprNode::at:
|
||||
{
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
// for now, just handle simple identifiers on the rhs.
|
||||
ret = genExpr(b->op1);
|
||||
if (b->op2->getKind() == ExprNode::identifier) {
|
||||
TypedRegister t;
|
||||
uint32 slotIndex;
|
||||
const StringAtom &name = (static_cast<IdentifierExprNode *>(b->op2))->name;
|
||||
LValueKind lvk = resolveIdentifier(name, t, slotIndex);
|
||||
ASSERT(t.second == &Type_Type);
|
||||
const JSValue &v = mGlobal->getVariable(name);
|
||||
ASSERT(v.isType());
|
||||
JSClass *clazz = dynamic_cast<JSClass*>(v.type);
|
||||
if (clazz)
|
||||
ret = cast(ret, clazz);
|
||||
else
|
||||
ret = cast(ret, t.second);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("Anything more complex than <expr>@<name> is not implemented");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
NOT_REACHED("Unsupported ExprNode kind");
|
||||
|
@ -260,6 +260,8 @@ namespace ICG {
|
||||
TypedRegister newArray();
|
||||
TypedRegister newFunction(ICodeModule *icm);
|
||||
TypedRegister newClass(JSClass *clazz);
|
||||
|
||||
TypedRegister cast(TypedRegister arg, JSType *toType);
|
||||
|
||||
TypedRegister super();
|
||||
TypedRegister loadName(const StringAtom &name);
|
||||
|
@ -481,6 +481,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
||||
assert(mPC != endPC);
|
||||
Instruction* instruction = *mPC;
|
||||
switch (instruction->op()) {
|
||||
case CAST:
|
||||
{
|
||||
Cast* c = static_cast<Cast*>(instruction);
|
||||
JSType *toType = op3(c);
|
||||
(*registers)[dst(c).first] = (*registers)[src1(c).first];
|
||||
}
|
||||
break;
|
||||
case SUPER:
|
||||
{
|
||||
Super* su = static_cast<Super*>(instruction);
|
||||
@ -710,28 +717,6 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
||||
JSClass* thisClass = src1(nc);
|
||||
JSInstance* thisInstance = new(thisClass) JSInstance(thisClass);
|
||||
(*registers)[dst(nc).first] = thisInstance;
|
||||
/*
|
||||
JSValues args(1);
|
||||
args[0] = thisInstance;
|
||||
TypedRegister voidRegister(NotARegister, &None_Type);
|
||||
InstructionIterator nextPC = ++mPC;
|
||||
do {
|
||||
// call the constructor(s), if any.
|
||||
ICodeModule* init = thisClass->getInitializer();
|
||||
if (init) {
|
||||
mLinkage = new Linkage(mLinkage, nextPC,
|
||||
mActivation, mGlobal, voidRegister);
|
||||
mActivation = new Activation(init, args);
|
||||
registers = &mActivation->mRegisters;
|
||||
nextPC = init->its_iCode->begin();
|
||||
endPC = init->its_iCode->end();
|
||||
}
|
||||
thisClass = thisClass->getSuperClass();
|
||||
} while (thisClass);
|
||||
|
||||
mPC = nextPC;
|
||||
continue;
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case NEW_FUNCTION:
|
||||
|
@ -341,7 +341,7 @@ class Tracer : public Context::Listener {
|
||||
char * tests[] = {
|
||||
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
|
||||
"a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" ,
|
||||
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s()); print(A.b); return;"
|
||||
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s(), \" should be 3\"); print(A.b, \" should be 4\"); return;"
|
||||
};
|
||||
|
||||
static void testCompile()
|
||||
|
@ -136,7 +136,7 @@ $ops{"NEW_FUNCTION"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, ICodeModule",
|
||||
params => [ ("TypedRegister", "ICodeModule *") ]
|
||||
params => [ ("TypedRegister", "ICodeModule*") ]
|
||||
};
|
||||
$ops{"NEW_ARRAY"} =
|
||||
{
|
||||
@ -342,6 +342,12 @@ $ops{"WITHOUT"} =
|
||||
super => "Instruction",
|
||||
rem => "without this object",
|
||||
};
|
||||
$ops{"CAST"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, rvalue, toType",
|
||||
params => [ ("TypedRegister", "TypedRegister", "JSType*") ]
|
||||
};
|
||||
|
||||
#
|
||||
# nasty perl code, you probably don't need to muck around below this line
|
||||
@ -539,6 +545,8 @@ sub get_print_body {
|
||||
push (@oplist, "\"Offset \" << ((mOp$op) ? mOp$op->mOffset : NotAnOffset)")
|
||||
} elsif ($type =~ /String/) {
|
||||
push (@oplist, "\"'\" << *mOp$op << \"'\"");
|
||||
} elsif ($type =~ /JSType\*/) {
|
||||
push (@oplist, "\"'\" << *mOp$op << \"'\"");
|
||||
} elsif ($type =~ /bool/) {
|
||||
push (@oplist, "\"'\" << ((mOp$op) ? \"true\" : \"false\") << \"'\"");
|
||||
} elsif ($type =~ /ICodeModule/) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
BRANCH_FALSE, /* target label, condition */
|
||||
BRANCH_TRUE, /* target label, condition */
|
||||
CALL, /* result, target, name, args */
|
||||
CAST, /* dest, rvalue, toType */
|
||||
COMPARE_EQ, /* dest, source1, source2 */
|
||||
COMPARE_GE, /* dest, source1, source2 */
|
||||
COMPARE_GT, /* dest, source1, source2 */
|
||||
@ -158,6 +159,22 @@
|
||||
}
|
||||
};
|
||||
|
||||
class Cast : public Instruction_3<TypedRegister, TypedRegister, JSType*> {
|
||||
public:
|
||||
/* dest, rvalue, toType */
|
||||
Cast (TypedRegister aOp1, TypedRegister aOp2, JSType* aOp3) :
|
||||
Instruction_3<TypedRegister, TypedRegister, JSType*>
|
||||
(CAST, aOp1, aOp2, aOp3) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[CAST] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'";
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
class CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* dest, source1, source2 */
|
||||
@ -550,11 +567,11 @@
|
||||
}
|
||||
};
|
||||
|
||||
class NewFunction : public Instruction_2<TypedRegister, ICodeModule *> {
|
||||
class NewFunction : public Instruction_2<TypedRegister, ICodeModule*> {
|
||||
public:
|
||||
/* dest, ICodeModule */
|
||||
NewFunction (TypedRegister aOp1, ICodeModule * aOp2) :
|
||||
Instruction_2<TypedRegister, ICodeModule *>
|
||||
NewFunction (TypedRegister aOp1, ICodeModule* aOp2) :
|
||||
Instruction_2<TypedRegister, ICodeModule*>
|
||||
(NEW_FUNCTION, aOp1, aOp2) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[NEW_FUNCTION] << "\t" << "R" << mOp1.first << ", " << "ICodeModule";
|
||||
@ -1035,6 +1052,7 @@
|
||||
"BRANCH_FALSE ",
|
||||
"BRANCH_TRUE ",
|
||||
"CALL ",
|
||||
"CAST ",
|
||||
"COMPARE_EQ ",
|
||||
"COMPARE_GE ",
|
||||
"COMPARE_GT ",
|
||||
|
@ -482,6 +482,14 @@ TypedRegister ICodeGenerator::super()
|
||||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::cast(TypedRegister arg, JSType *toType)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), toType);
|
||||
Cast *instr = new Cast(dest, arg, toType);
|
||||
iCode->push_back(instr);
|
||||
return dest;
|
||||
}
|
||||
|
||||
void ICodeGenerator::branch(Label *label)
|
||||
{
|
||||
Branch *instr = new Branch(label);
|
||||
@ -1216,17 +1224,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
ret = genExpr(b->op2);
|
||||
if (b->op1->getKind() == ExprNode::identifier) {
|
||||
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
|
||||
/*
|
||||
if (!isWithinWith()) {
|
||||
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
if (v.first != NotARegister)
|
||||
move(v, ret);
|
||||
else
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
}
|
||||
else
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
*/
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::dot) {
|
||||
@ -1259,27 +1256,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
ret = genExpr(b->op2);
|
||||
if (b->op1->getKind() == ExprNode::identifier) {
|
||||
|
||||
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
|
||||
/*
|
||||
if (!isWithinWith()) {
|
||||
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
if (v.first != NotARegister) {
|
||||
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
move(v, ret);
|
||||
}
|
||||
else {
|
||||
v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TypedRegister v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
|
||||
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
|
||||
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
if (b->op1->getKind() == ExprNode::dot) {
|
||||
@ -1463,6 +1440,31 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
||||
}
|
||||
break;
|
||||
|
||||
case ExprNode::at:
|
||||
{
|
||||
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
|
||||
// for now, just handle simple identifiers on the rhs.
|
||||
ret = genExpr(b->op1);
|
||||
if (b->op2->getKind() == ExprNode::identifier) {
|
||||
TypedRegister t;
|
||||
uint32 slotIndex;
|
||||
const StringAtom &name = (static_cast<IdentifierExprNode *>(b->op2))->name;
|
||||
LValueKind lvk = resolveIdentifier(name, t, slotIndex);
|
||||
ASSERT(t.second == &Type_Type);
|
||||
const JSValue &v = mGlobal->getVariable(name);
|
||||
ASSERT(v.isType());
|
||||
JSClass *clazz = dynamic_cast<JSClass*>(v.type);
|
||||
if (clazz)
|
||||
ret = cast(ret, clazz);
|
||||
else
|
||||
ret = cast(ret, t.second);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("Anything more complex than <expr>@<name> is not implemented");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
NOT_REACHED("Unsupported ExprNode kind");
|
||||
|
@ -260,6 +260,8 @@ namespace ICG {
|
||||
TypedRegister newArray();
|
||||
TypedRegister newFunction(ICodeModule *icm);
|
||||
TypedRegister newClass(JSClass *clazz);
|
||||
|
||||
TypedRegister cast(TypedRegister arg, JSType *toType);
|
||||
|
||||
TypedRegister super();
|
||||
TypedRegister loadName(const StringAtom &name);
|
||||
|
@ -481,6 +481,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
||||
assert(mPC != endPC);
|
||||
Instruction* instruction = *mPC;
|
||||
switch (instruction->op()) {
|
||||
case CAST:
|
||||
{
|
||||
Cast* c = static_cast<Cast*>(instruction);
|
||||
JSType *toType = op3(c);
|
||||
(*registers)[dst(c).first] = (*registers)[src1(c).first];
|
||||
}
|
||||
break;
|
||||
case SUPER:
|
||||
{
|
||||
Super* su = static_cast<Super*>(instruction);
|
||||
@ -710,28 +717,6 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
||||
JSClass* thisClass = src1(nc);
|
||||
JSInstance* thisInstance = new(thisClass) JSInstance(thisClass);
|
||||
(*registers)[dst(nc).first] = thisInstance;
|
||||
/*
|
||||
JSValues args(1);
|
||||
args[0] = thisInstance;
|
||||
TypedRegister voidRegister(NotARegister, &None_Type);
|
||||
InstructionIterator nextPC = ++mPC;
|
||||
do {
|
||||
// call the constructor(s), if any.
|
||||
ICodeModule* init = thisClass->getInitializer();
|
||||
if (init) {
|
||||
mLinkage = new Linkage(mLinkage, nextPC,
|
||||
mActivation, mGlobal, voidRegister);
|
||||
mActivation = new Activation(init, args);
|
||||
registers = &mActivation->mRegisters;
|
||||
nextPC = init->its_iCode->begin();
|
||||
endPC = init->its_iCode->end();
|
||||
}
|
||||
thisClass = thisClass->getSuperClass();
|
||||
} while (thisClass);
|
||||
|
||||
mPC = nextPC;
|
||||
continue;
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case NEW_FUNCTION:
|
||||
|
@ -341,7 +341,7 @@ class Tracer : public Context::Listener {
|
||||
char * tests[] = {
|
||||
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
|
||||
"a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" ,
|
||||
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s()); print(A.b); return;"
|
||||
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s(), \" should be 3\"); print(A.b, \" should be 4\"); return;"
|
||||
};
|
||||
|
||||
static void testCompile()
|
||||
|
@ -136,7 +136,7 @@ $ops{"NEW_FUNCTION"} =
|
||||
{
|
||||
super => "Instruction_2",
|
||||
rem => "dest, ICodeModule",
|
||||
params => [ ("TypedRegister", "ICodeModule *") ]
|
||||
params => [ ("TypedRegister", "ICodeModule*") ]
|
||||
};
|
||||
$ops{"NEW_ARRAY"} =
|
||||
{
|
||||
@ -342,6 +342,12 @@ $ops{"WITHOUT"} =
|
||||
super => "Instruction",
|
||||
rem => "without this object",
|
||||
};
|
||||
$ops{"CAST"} =
|
||||
{
|
||||
super => "Instruction_3",
|
||||
rem => "dest, rvalue, toType",
|
||||
params => [ ("TypedRegister", "TypedRegister", "JSType*") ]
|
||||
};
|
||||
|
||||
#
|
||||
# nasty perl code, you probably don't need to muck around below this line
|
||||
@ -539,6 +545,8 @@ sub get_print_body {
|
||||
push (@oplist, "\"Offset \" << ((mOp$op) ? mOp$op->mOffset : NotAnOffset)")
|
||||
} elsif ($type =~ /String/) {
|
||||
push (@oplist, "\"'\" << *mOp$op << \"'\"");
|
||||
} elsif ($type =~ /JSType\*/) {
|
||||
push (@oplist, "\"'\" << *mOp$op << \"'\"");
|
||||
} elsif ($type =~ /bool/) {
|
||||
push (@oplist, "\"'\" << ((mOp$op) ? \"true\" : \"false\") << \"'\"");
|
||||
} elsif ($type =~ /ICodeModule/) {
|
||||
|
Loading…
Reference in New Issue
Block a user