[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/work/kjs-frostbyte/kjs/bytecode
From:       Maks Orlovich <maksim () kde ! org>
Date:       2008-02-27 17:07:54
Message-ID: 1204132074.637993.11198.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 779974 by orlovich:

- Support the notion of overloads in tablebuilder.

 M  +1 -0      generator/lexer.cpp  
 M  +1 -0      generator/lexer.h  
 M  +3 -3      generator/parser.cpp  
 M  +3 -2      generator/parser.h  
 M  +11 -3     generator/tablebuilder.cpp  
 M  +4 -2      generator/tablebuilder.h  
 M  +32 -12    opcodes.cpp.in  
 M  +7 -1      opcodes.h.in  


--- branches/work/kjs-frostbyte/kjs/bytecode/generator/lexer.cpp #779973:779974
@@ -39,6 +39,7 @@
     keywords["operation"]   = Operation;
     keywords["costs"]       = Costs;
     keywords["impl"]        = Impl;
+    keywords["overload"]    = Overload;
     keywords["tile"]        = Tile;
     keywords["as"]          = As;
     keywords["align8"]      = Align8;
--- branches/work/kjs-frostbyte/kjs/bytecode/generator/lexer.h #779973:779974
@@ -56,6 +56,7 @@
         Operation,
         Costs,
         Impl,
+        Overload,
         Tile,
         As,
         Align8,
--- branches/work/kjs-frostbyte/kjs/bytecode/generator/parser.cpp #779973:779974
@@ -244,7 +244,7 @@
 
     match(Lexer::LBrace);
     Lexer::Token tok = peekNext();
-    while (tok.type == Lexer::Tile || tok.type == Lexer::Impl) {
+    while (tok.type == Lexer::Tile || tok.type == Lexer::Impl || tok.type == \
Lexer::Overload) {  if (tok.type == Lexer::Tile)
             parseTile();
         else
@@ -260,7 +260,7 @@
     // paramList := ident ident
     // paramList := ident ident , paramList
 
-    match(Lexer::Impl);
+    bool overload = getNext().type == Lexer::Overload;
 
     QString ret = matchIdentifier();
 
@@ -294,7 +294,7 @@
     QString code = matchCode(codeLine);
 
 
-    handleImpl(fn, code, codeLine, cost, ret, paramSigs, paramNames);
+    handleImpl(fn, code, overload, codeLine, cost, ret, paramSigs, paramNames);
 }
 
 void Parser::parseTile()
--- branches/work/kjs-frostbyte/kjs/bytecode/generator/parser.h #779973:779974
@@ -43,8 +43,9 @@
                                   bool immediate, bool checked, bool mayThrow,
                                   const QString& from, const QString& to, int cost) \
= 0;  virtual void handleOperation(const QString& name) = 0;
-    virtual void handleImpl(const QString& fnName, const QString& code, int \
                codeLine, int cost,
-                            const QString& retType, QStringList sig, QStringList \
paramNames) = 0; +    virtual void handleImpl(const QString& fnName, const QString& \
code, bool overload, +                            int codeLine, int cost, const \
QString& retType, QStringList sig, +                            QStringList \
paramNames) = 0;  virtual void handleTile(const QString& fnName, QStringList sig) = \
0;  
     QString matchIdentifier();
--- branches/work/kjs-frostbyte/kjs/bytecode/generator/tablebuilder.cpp \
#779973:779974 @@ -356,7 +356,7 @@
         names << "in";
         QString patchedCode = code;
         patchedCode.replace("return", "$$ = "); // ### FIXME: Brittle!
-        handleImpl("", patchedCode, codeLine, 0, to, sig, names);
+        handleImpl("", patchedCode, false,codeLine, 0, to, sig, names);
     }
 }
 
@@ -377,7 +377,7 @@
     return sig;
 }
 
-void TableBuilder::handleImpl(const QString& fnName, const QString& code, int \
codeLine, int cost, +void TableBuilder::handleImpl(const QString& fnName, const \
                QString& code, bool ol, int codeLine, int cost,
                               const QString& retType, QStringList sig, QStringList \
paramNames)  {
     // If the return type isn't 'void', we prepend a destination register as a \
parameter in the encoding. @@ -395,6 +395,7 @@
     Operation op;
     op.name           = operationNames.last();
     op.retType        = retType;
+    op.overload       = ol;
     operationRetTypes[op.name] = retType;
     op.implementAs    = code;
     op.codeLine       = codeLine;
@@ -425,6 +426,7 @@
     op.implementAs = impl.implementAs;
     op.codeLine    = impl.codeLine;
     op.retType     = impl.retType;
+    op.overload    = impl.overload; // if original required precise matching, so did \
the tile.  op.parameters  = resolveSignature(extSig);
     op.implParams     = impl.implParams;
     op.implParamNames = impl.implParamNames;
@@ -534,6 +536,9 @@
     }
     *cppStream << "}, ";
 
+    // Return type.
+    *cppStream << "OpType_" << variant.op.retType << ", ";
+
     int adjust = doPad ? 4 : 0; // padded version has 4 extra bytes,
                                 // between the opcode and the first arg.
     // Size..
@@ -553,8 +558,11 @@
     *cppStream << (doPad ? "true" : "false") << ", ";
 
     // And whether a padded version exists.
-    *cppStream << (hasPadVariant ? "true" : "false");
+    *cppStream << (hasPadVariant ? "true" : "false") << ", ";
 
+    // Whether this is an overload, requiring precise matching
+    *cppStream << (variant.op.overload ? "true" : "false");
+
     if (needsComma)
         *cppStream << "},\n";
     else
--- branches/work/kjs-frostbyte/kjs/bytecode/generator/tablebuilder.h #779973:779974
@@ -64,6 +64,7 @@
     QList<Type>  parameters;
     int          cost;
     int          codeLine;
+    bool         overload;
 
     QString implementAs;
     QList<Type> implParams;
@@ -96,8 +97,9 @@
                                   const QString& from, const QString& to, int cost);
 
     virtual void handleOperation(const QString& name);
-    virtual void handleImpl(const QString& fnName, const QString& code, int \
                codeLine, int cost,
-                            const QString& retType, QStringList sig, QStringList \
paramNames); +    virtual void handleImpl(const QString& fnName, const QString& code, \
bool overload, +                            int codeLine, int cost, const QString& \
retType, QStringList sig, +                            QStringList paramNames);
     virtual void handleTile(const QString& fnName, QStringList sig);
 
     void printConversionInfo(const QHash<QString, QHash<QString, ConversionInfo> >& \
                table, bool last);
--- branches/work/kjs-frostbyte/kjs/bytecode/opcodes.cpp.in #779973:779974
@@ -32,11 +32,21 @@
 @generate
 
 // Note: costOut will be negative if no conversion is possible
-ConvOp computeCast(const OpValue* in, OpType outType, bool outImmediate, int& \
costOut) +ConvOp computeCast(const OpValue* in, OpType outType, bool outImmediate, \
int& costOut, bool exact)  {
     bool   inImmediate = in->immediate;
     OpType inType      = in->type;
 
+    if (exact) {
+        if (inImmediate == outImmediate && inType == outType) {
+            costOut = 0;
+            return Conv_NoOp;
+        }
+
+        costOut = Cost_NoConversion;
+        return Conv_NoConversion;
+    }
+
     // Look up in the table..
     const ConvInfo* inf = getConversionInfo(inImmediate, inType, outType);
 
@@ -130,7 +140,7 @@
                             OpType outType, OpValue* out)
 {
     int cost;
-    ConvOp op = computeCast(in, outType, in->immediate, cost);
+    ConvOp op = computeCast(in, outType, in->immediate, cost, false);
     ASSERT(cost >= 0);
     emitConversion(comp, block, in->immediate, op, in, *out);
 }
@@ -168,20 +178,17 @@
     int    cheapestCost = 0;
     ConvOp cheapestConvOps[3] = {Conv_NoConversion, Conv_NoConversion, \
Conv_NoConversion};  
+    // Here, we assume that all methods either return or not.
     OpType retType = opRetTypes[baseInstr];
     OpValue retVal, retReg;
     if (retType != OpType_void) {
-        // Add in a register argument..
+        // Add in a register argument.. For now just a dummy #;
+        // will fill in w/appropriate type later
         ASSERT(!a2);
-        comp->requestTemporary(retType, retVal, retReg);
-
+        retReg = OpValue::immRegNum(-1);
         a2 = a1;
         a1 = a0;
         a0 = &retReg;
-
-        // Set return value, if needed
-        if (retOut)
-            *retOut = retVal;
     } else {
         ASSERT(!retOut);
     }
@@ -205,18 +212,20 @@
         if (cand->padAlign)
             continue;
 
+        bool exact = cand->matchExactly;
+
         int    cost0 = 0, cost1 = 0, cost2 = 0;
         ConvOp convOps[3];
 
         switch (numArgs) {
         case 3:
-            convOps[2] = computeCast(a2, cand->paramTypes[2], \
cand->immediateParams[2], cost2); +            convOps[2] = computeCast(a2, \
cand->paramTypes[2], cand->immediateParams[2], cost2, exact);  // Fallthrough
         case 2:
-            convOps[1] = computeCast(a1, cand->paramTypes[1], \
cand->immediateParams[1], cost1); +            convOps[1] = computeCast(a1, \
cand->paramTypes[1], cand->immediateParams[1], cost1, exact);  // Fallthrough
         case 1:
-            convOps[0] = computeCast(a0, cand->paramTypes[0], \
cand->immediateParams[0], cost0); +            convOps[0] = computeCast(a0, \
cand->paramTypes[0], cand->immediateParams[0], cost0, exact);  // Fallthrough
         case 0:
             break;
@@ -247,6 +256,17 @@
         CRASH(); // Should never happen!
     }
 
+
+    // Now that we have a candidate, actually grab a register of the proper return \
type. +    retType = cheapest->retType;
+    if (retType != OpType_void) {
+        comp->requestTemporary(retType, retVal, retReg);
+
+        // Set return value, if needed
+        if (retOut)
+            *retOut = retVal;
+    }
+
     OpValue c0, c1, c2; // Converted versions, if needed.
 
     switch (numArgs) {
--- branches/work/kjs-frostbyte/kjs/bytecode/opcodes.h.in #779973:779974
@@ -65,6 +65,8 @@
     OpType paramTypes[3];
     bool   immediateParams[3];
 
+    OpType retType; // type of this specialization
+
     int length; // Length of instruction, including opcode + args
 
     // This contains offsets of arguments, starting from before the instruction
@@ -76,6 +78,10 @@
 
     // If this is true, this version has both padded and unpadded flavors
     bool hasPadVariant;
+
+    // If this is true, this is an overload specializations which
+    // should be matched exactly, w/o conversions
+    bool matchExactly;
 };
 
 // The main array of Op instances, mapped by OpByteCode
@@ -88,7 +94,7 @@
 // Describes whether the type is align8 or not.
 extern const bool opTypeIsAlign8[];
 
-struct OpValue;
+class OpValue;
 
 typedef Vector<unsigned char> CodeBlock;
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic