Changeset 26925 in webkit for trunk/JavaScriptCore/kjs/nodes.cpp


Ignore:
Timestamp:
Oct 23, 2007, 2:25:44 PM (18 years ago)
Author:
oliver
Message:

Separating all of the simple binary expression nodes into multiple classes

Reviewed by Maciej

Separating all of the simple (eg. non-read-modify-write) binary operators into separate classes in preparation for further JS optimisations.

Happily this produces a 0.8% to 1.0% performance increase in SunSpider with no further work.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r26914 r26925  
    11841184}
    11851185
    1186 // ------------------------------ MultNode -------------------------------------
    1187 
    1188 // ECMA 11.5
     1186// ------------------------------ Multiplicative Nodes -----------------------------------
     1187
     1188// ECMA 11.5.1
    11891189JSValue *MultNode::evaluate(ExecState *exec)
    11901190{
     1191    JSValue *v1 = term1->evaluate(exec);
     1192    KJS_CHECKEXCEPTIONVALUE
     1193       
     1194    JSValue *v2 = term2->evaluate(exec);
     1195    KJS_CHECKEXCEPTIONVALUE
     1196       
     1197    return mult(exec, v1, v2, '*');
     1198}
     1199
     1200// ECMA 11.5.2
     1201JSValue *DivNode::evaluate(ExecState *exec)
     1202{
     1203    JSValue *v1 = term1->evaluate(exec);
     1204    KJS_CHECKEXCEPTIONVALUE
     1205       
     1206    JSValue *v2 = term2->evaluate(exec);
     1207    KJS_CHECKEXCEPTIONVALUE
     1208       
     1209    return mult(exec, v1, v2, '/');
     1210}
     1211
     1212// ECMA 11.5.3
     1213JSValue *ModNode::evaluate(ExecState *exec)
     1214{
     1215    JSValue *v1 = term1->evaluate(exec);
     1216    KJS_CHECKEXCEPTIONVALUE
     1217       
     1218    JSValue *v2 = term2->evaluate(exec);
     1219    KJS_CHECKEXCEPTIONVALUE
     1220       
     1221    return mult(exec, v1, v2, '%');
     1222}
     1223
     1224// ------------------------------ Additive Nodes --------------------------------------
     1225
     1226// ECMA 11.6.1
     1227JSValue *AddNode::evaluate(ExecState *exec)
     1228{
    11911229  JSValue *v1 = term1->evaluate(exec);
    11921230  KJS_CHECKEXCEPTIONVALUE
     
    11951233  KJS_CHECKEXCEPTIONVALUE
    11961234
    1197   return mult(exec, v1, v2, oper);
    1198 }
    1199 
    1200 // ------------------------------ AddNode --------------------------------------
    1201 
    1202 // ECMA 11.6
    1203 JSValue *AddNode::evaluate(ExecState *exec)
    1204 {
    1205   JSValue *v1 = term1->evaluate(exec);
    1206   KJS_CHECKEXCEPTIONVALUE
    1207 
    1208   JSValue *v2 = term2->evaluate(exec);
    1209   KJS_CHECKEXCEPTIONVALUE
    1210 
    1211   return add(exec, v1, v2, oper);
    1212 }
    1213 
    1214 // ------------------------------ ShiftNode ------------------------------------
    1215 
    1216 // ECMA 11.7
    1217 JSValue *ShiftNode::evaluate(ExecState *exec)
     1235  return add(exec, v1, v2, '+');
     1236}
     1237
     1238
     1239// ECMA 11.6.2
     1240JSValue *SubNode::evaluate(ExecState *exec)
     1241{
     1242    JSValue *v1 = term1->evaluate(exec);
     1243    KJS_CHECKEXCEPTIONVALUE
     1244       
     1245    JSValue *v2 = term2->evaluate(exec);
     1246    KJS_CHECKEXCEPTIONVALUE
     1247       
     1248    return add(exec, v1, v2, '-');
     1249}
     1250
     1251// ------------------------------ Shift Nodes ------------------------------------
     1252
     1253// ECMA 11.7.1
     1254JSValue *LeftShiftNode::evaluate(ExecState *exec)
    12181255{
    12191256  JSValue *v1 = term1->evaluate(exec);
     
    12241261  i2 &= 0x1f;
    12251262
    1226   switch (oper) {
    1227   case OpLShift:
    1228     return jsNumber(v1->toInt32(exec) << i2);
    1229   case OpRShift:
    1230     return jsNumber(v1->toInt32(exec) >> i2);
    1231   case OpURShift:
    1232     return jsNumber(v1->toUInt32(exec) >> i2);
    1233   default:
    1234     ASSERT(!"ShiftNode: unhandled switch case");
    1235     return jsUndefined();
    1236   }
    1237 }
    1238 
    1239 // ------------------------------ RelationalNode -------------------------------
    1240 
    1241 // ECMA 11.8
    1242 JSValue *RelationalNode::evaluate(ExecState *exec)
     1263  return jsNumber(v1->toInt32(exec) << i2);
     1264}
     1265
     1266// ECMA 11.7.2
     1267JSValue *RightShiftNode::evaluate(ExecState *exec)
     1268{
     1269  JSValue *v1 = term1->evaluate(exec);
     1270  KJS_CHECKEXCEPTIONVALUE
     1271  JSValue *v2 = term2->evaluate(exec);
     1272  KJS_CHECKEXCEPTIONVALUE
     1273  unsigned int i2 = v2->toUInt32(exec);
     1274  i2 &= 0x1f;
     1275
     1276  return jsNumber(v1->toInt32(exec) >> i2);
     1277}
     1278
     1279// ECMA 11.7.3
     1280JSValue *UnsignedRightShiftNode::evaluate(ExecState *exec)
     1281{
     1282  JSValue *v1 = term1->evaluate(exec);
     1283  KJS_CHECKEXCEPTIONVALUE
     1284  JSValue *v2 = term2->evaluate(exec);
     1285  KJS_CHECKEXCEPTIONVALUE
     1286  unsigned int i2 = v2->toUInt32(exec);
     1287  i2 &= 0x1f;
     1288
     1289  return jsNumber(v1->toUInt32(exec) >> i2);
     1290}
     1291
     1292// ------------------------------ Relational Nodes -------------------------------
     1293
     1294// ECMA 11.8.1
     1295JSValue *LessNode::evaluate(ExecState *exec)
    12431296{
    12441297  JSValue *v1 = expr1->evaluate(exec);
     
    12461299  JSValue *v2 = expr2->evaluate(exec);
    12471300  KJS_CHECKEXCEPTIONVALUE
    1248 
    1249   bool b;
    1250   if (oper == OpLess || oper == OpGreaterEq) {
    1251     int r = relation(exec, v1, v2);
    1252     if (r < 0)
    1253       b = false;
    1254     else
    1255       b = (oper == OpLess) ? (r == 1) : (r == 0);
    1256   } else if (oper == OpGreater || oper == OpLessEq) {
    1257     int r = relation(exec, v2, v1);
    1258     if (r < 0)
    1259       b = false;
    1260     else
    1261       b = (oper == OpGreater) ? (r == 1) : (r == 0);
    1262   } else if (oper == OpIn) {
    1263       // Is all of this OK for host objects?
    1264       if (!v2->isObject())
    1265           return throwError(exec,  TypeError,
    1266                              "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2.get());
    1267       JSObject *o2(static_cast<JSObject*>(v2));
    1268       b = o2->hasProperty(exec, Identifier(v1->toString(exec)));
    1269   } else {
    1270     if (!v2->isObject())
    1271         return throwError(exec,  TypeError,
    1272                            "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
    1273 
    1274     JSObject *o2(static_cast<JSObject*>(v2));
    1275     if (!o2->implementsHasInstance())
     1301  int r = relation(exec, v1, v2);
     1302  if (r < 0)
     1303      return jsBoolean(false);
     1304  return jsBoolean(r == 1);
     1305}
     1306
     1307// ECMA 11.8.2
     1308JSValue *GreaterNode::evaluate(ExecState *exec)
     1309{
     1310  JSValue *v1 = expr1->evaluate(exec);
     1311  KJS_CHECKEXCEPTIONVALUE
     1312  JSValue *v2 = expr2->evaluate(exec);
     1313  KJS_CHECKEXCEPTIONVALUE
     1314  int r = relation(exec, v2, v1);
     1315  if (r < 0)
     1316      return jsBoolean(false);
     1317  return jsBoolean(r == 1);
     1318}
     1319
     1320// ECMA 11.8.3
     1321JSValue *LessEqNode::evaluate(ExecState *exec)
     1322{
     1323  JSValue *v1 = expr1->evaluate(exec);
     1324  KJS_CHECKEXCEPTIONVALUE
     1325  JSValue *v2 = expr2->evaluate(exec);
     1326  KJS_CHECKEXCEPTIONVALUE
     1327  int r = relation(exec, v2, v1);
     1328  if (r < 0)
     1329      return jsBoolean(false);
     1330  return jsBoolean(r == 0);
     1331}
     1332
     1333// ECMA 11.8.4
     1334JSValue *GreaterEqNode::evaluate(ExecState *exec)
     1335{
     1336  JSValue *v1 = expr1->evaluate(exec);
     1337  KJS_CHECKEXCEPTIONVALUE
     1338  JSValue *v2 = expr2->evaluate(exec);
     1339  KJS_CHECKEXCEPTIONVALUE
     1340  int r = relation(exec, v1, v2);
     1341  if (r < 0)
     1342      return jsBoolean(false);
     1343  return jsBoolean(r == 0);
     1344}
     1345
     1346// ECMA 11.8.6
     1347JSValue *InstanceOfNode::evaluate(ExecState *exec)
     1348{
     1349  JSValue *v1 = expr1->evaluate(exec);
     1350  KJS_CHECKEXCEPTIONVALUE
     1351  JSValue *v2 = expr2->evaluate(exec);
     1352  KJS_CHECKEXCEPTIONVALUE
     1353
     1354  if (!v2->isObject())
     1355      return throwError(exec,  TypeError,
     1356                          "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
     1357
     1358  JSObject *o2(static_cast<JSObject*>(v2));
     1359  if (!o2->implementsHasInstance())
    12761360      // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
    12771361      // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
     
    12791363      // case we return false (consistent with mozilla)
    12801364      return jsBoolean(false);
    1281     return jsBoolean(o2->hasInstance(exec, v1));
    1282   }
    1283 
    1284   return jsBoolean(b);
    1285 }
    1286 
    1287 // ------------------------------ EqualNode ------------------------------------
    1288 
    1289 // ECMA 11.9
     1365  return jsBoolean(o2->hasInstance(exec, v1));
     1366}
     1367
     1368// ECMA 11.8.7
     1369JSValue *InNode::evaluate(ExecState *exec)
     1370{
     1371  JSValue *v1 = expr1->evaluate(exec);
     1372  KJS_CHECKEXCEPTIONVALUE
     1373  JSValue *v2 = expr2->evaluate(exec);
     1374  KJS_CHECKEXCEPTIONVALUE
     1375
     1376  // Is all of this OK for host objects?
     1377  if (!v2->isObject())
     1378      return throwError(exec,  TypeError,
     1379                         "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2.get());
     1380  JSObject *o2(static_cast<JSObject*>(v2));
     1381  return jsBoolean(o2->hasProperty(exec, Identifier(v1->toString(exec))));
     1382}
     1383
     1384// ------------------------------ Equality Nodes ------------------------------------
     1385
     1386// ECMA 11.9.1
    12901387JSValue *EqualNode::evaluate(ExecState *exec)
    12911388{
     
    12951392  KJS_CHECKEXCEPTIONVALUE
    12961393
    1297   bool result;
    1298   if (oper == OpEqEq || oper == OpNotEq) {
    1299     // == and !=
    1300     bool eq = equal(exec,v1, v2);
    1301     result = oper == OpEqEq ? eq : !eq;
    1302   } else {
    1303     // === and !==
    1304     bool eq = strictEqual(exec,v1, v2);
    1305     result = oper == OpStrEq ? eq : !eq;
    1306   }
    1307   return jsBoolean(result);
    1308 }
    1309 
    1310 // ------------------------------ BitOperNode ----------------------------------
     1394  return jsBoolean(equal(exec,v1, v2));
     1395}
     1396
     1397// ECMA 11.9.2
     1398JSValue *NotEqualNode::evaluate(ExecState *exec)
     1399{
     1400  JSValue *v1 = expr1->evaluate(exec);
     1401  KJS_CHECKEXCEPTIONVALUE
     1402  JSValue *v2 = expr2->evaluate(exec);
     1403  KJS_CHECKEXCEPTIONVALUE
     1404
     1405  return jsBoolean(!equal(exec,v1, v2));
     1406}
     1407
     1408// ECMA 11.9.4
     1409JSValue *StrictEqualNode::evaluate(ExecState *exec)
     1410{
     1411  JSValue *v1 = expr1->evaluate(exec);
     1412  KJS_CHECKEXCEPTIONVALUE
     1413  JSValue *v2 = expr2->evaluate(exec);
     1414  KJS_CHECKEXCEPTIONVALUE
     1415
     1416  return jsBoolean(strictEqual(exec,v1, v2));
     1417}
     1418
     1419// ECMA 11.9.5
     1420JSValue *NotStrictEqualNode::evaluate(ExecState *exec)
     1421{
     1422  JSValue *v1 = expr1->evaluate(exec);
     1423  KJS_CHECKEXCEPTIONVALUE
     1424  JSValue *v2 = expr2->evaluate(exec);
     1425  KJS_CHECKEXCEPTIONVALUE
     1426
     1427  return jsBoolean(!strictEqual(exec,v1, v2));
     1428}
     1429
     1430// ------------------------------ Bit Operation Nodes ----------------------------------
    13111431
    13121432// ECMA 11.10
    1313 JSValue *BitOperNode::evaluate(ExecState *exec)
     1433JSValue *BitAndNode::evaluate(ExecState *exec)
    13141434{
    13151435  JSValue *v1 = expr1->evaluate(exec);
     
    13171437  JSValue *v2 = expr2->evaluate(exec);
    13181438  KJS_CHECKEXCEPTIONVALUE
    1319   int i1 = v1->toInt32(exec);
    1320   int i2 = v2->toInt32(exec);
    1321   int result;
    1322   if (oper == OpBitAnd)
    1323     result = i1 & i2;
    1324   else if (oper == OpBitXOr)
    1325     result = i1 ^ i2;
    1326   else
    1327     result = i1 | i2;
    1328 
    1329   return jsNumber(result);
    1330 }
    1331 
    1332 // ------------------------------ BinaryLogicalNode ----------------------------
     1439 
     1440  return jsNumber(v1->toInt32(exec) & v2->toInt32(exec));
     1441}
     1442
     1443JSValue *BitXOrNode::evaluate(ExecState *exec)
     1444{
     1445  JSValue *v1 = expr1->evaluate(exec);
     1446  KJS_CHECKEXCEPTIONVALUE
     1447  JSValue *v2 = expr2->evaluate(exec);
     1448  KJS_CHECKEXCEPTIONVALUE
     1449 
     1450  return jsNumber(v1->toInt32(exec) ^ v2->toInt32(exec));
     1451}
     1452
     1453JSValue *BitOrNode::evaluate(ExecState *exec)
     1454{
     1455  JSValue *v1 = expr1->evaluate(exec);
     1456  KJS_CHECKEXCEPTIONVALUE
     1457  JSValue *v2 = expr2->evaluate(exec);
     1458  KJS_CHECKEXCEPTIONVALUE
     1459 
     1460  return jsNumber(v1->toInt32(exec) | v2->toInt32(exec));
     1461}
     1462
     1463// ------------------------------ Binary Logical Nodes ----------------------------
    13331464
    13341465// ECMA 11.11
    1335 JSValue *BinaryLogicalNode::evaluate(ExecState *exec)
     1466JSValue *LogicalAndNode::evaluate(ExecState *exec)
    13361467{
    13371468  JSValue *v1 = expr1->evaluate(exec);
    13381469  KJS_CHECKEXCEPTIONVALUE
    13391470  bool b1 = v1->toBoolean(exec);
    1340   if ((!b1 && oper == OpAnd) || (b1 && oper == OpOr))
     1471  if (!b1)
     1472    return v1;
     1473
     1474  JSValue *v2 = expr2->evaluate(exec);
     1475  KJS_CHECKEXCEPTIONVALUE
     1476
     1477  return v2;
     1478}
     1479
     1480JSValue *LogicalOrNode::evaluate(ExecState *exec)
     1481{
     1482  JSValue *v1 = expr1->evaluate(exec);
     1483  KJS_CHECKEXCEPTIONVALUE
     1484  bool b1 = v1->toBoolean(exec);
     1485  if (b1)
    13411486    return v1;
    13421487
Note: See TracChangeset for help on using the changeset viewer.