Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.cpp

Issue 10670: Do another merge using nifty new merge script (CL for that coming soon). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca> 3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 1212
1213 1213
1214 RegisterID* CodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNod e* n) 1214 RegisterID* CodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNod e* n)
1215 { 1215 {
1216 emitOpcode(op_new_func_exp); 1216 emitOpcode(op_new_func_exp);
1217 instructions().append(r0->index()); 1217 instructions().append(r0->index());
1218 instructions().append(addConstant(n)); 1218 instructions().append(addConstant(n));
1219 return r0; 1219 return r0;
1220 } 1220 }
1221 1221
1222 RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterI D* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, uns igned endOffset) 1222 RegisterID* CodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterI D* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOff set, unsigned endOffset)
1223 { 1223 {
1224 return emitCall(op_call, dst, func, base, argumentsNode, divot, startOffset, endOffset); 1224 return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, star tOffset, endOffset);
1225 } 1225 }
1226 1226
1227 RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, Regis terID* base, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset) 1227 RegisterID* CodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, Regis terID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned star tOffset, unsigned endOffset)
1228 { 1228 {
1229 return emitCall(op_call_eval, dst, func, base, argumentsNode, divot, startOf fset, endOffset); 1229 return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1230 } 1230 }
1231 1231
1232 RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Register ID* func, RegisterID* base, ArgumentsNode* argumentsNode, unsigned divot, unsign ed startOffset, unsigned endOffset) 1232 RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Register ID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot , unsigned startOffset, unsigned endOffset)
1233 { 1233 {
1234 ASSERT(opcodeID == op_call || opcodeID == op_call_eval); 1234 ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1235 ASSERT(func->refCount()); 1235 ASSERT(func->refCount());
1236 ASSERT(!base || base->refCount()); 1236
1237 1237 if (m_shouldEmitProfileHooks) {
1238 // If codegen decided to recycle func as this call's destination registe r,
1239 // we need to undo that optimization here so that func will still be aro und
1240 // for the sake of op_profile_did_call.
1241 if (dst == func) {
1242 RefPtr<RegisterID> protect = thisRegister;
1243 RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), this Register);
1244 RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
1245
1246 thisRegister = movedThisRegister.release().releaseRef();
1247 func = movedFunc.release().releaseRef();
1248 }
1249 }
1250
1238 // Generate code for arguments. 1251 // Generate code for arguments.
1239 Vector<RefPtr<RegisterID>, 16> argv; 1252 Vector<RefPtr<RegisterID>, 16> argv;
1240 argv.append(newTemporary()); // reserve space for "this" 1253 argv.append(thisRegister);
1241 for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next .get()) { 1254 for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next .get()) {
1242 argv.append(newTemporary()); 1255 argv.append(newTemporary());
1243 emitNode(argv.last().get(), n); 1256 emitNode(argv.last().get(), n);
1244 } 1257 }
1245 1258
1246 // Reserve space for call frame. 1259 // Reserve space for call frame.
1247 Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; 1260 Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1248 for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) 1261 for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1249 callFrame.append(newTemporary()); 1262 callFrame.append(newTemporary());
1250 1263
1251 if (m_shouldEmitProfileHooks) { 1264 if (m_shouldEmitProfileHooks) {
1252 emitOpcode(op_profile_will_call); 1265 emitOpcode(op_profile_will_call);
1253 instructions().append(func->index()); 1266 instructions().append(func->index());
1254 } 1267 }
1255 1268
1256 emitExpressionInfo(divot, startOffset, endOffset); 1269 emitExpressionInfo(divot, startOffset, endOffset);
1257 m_codeBlock->callLinkInfos.append(CallLinkInfo()); 1270 m_codeBlock->callLinkInfos.append(CallLinkInfo());
1271
1272 // Emit call.
1258 emitOpcode(opcodeID); 1273 emitOpcode(opcodeID);
1259 instructions().append(dst->index()); 1274 instructions().append(dst->index()); // dst
1260 instructions().append(func->index()); 1275 instructions().append(func->index()); // func
1261 instructions().append(base ? base->index() : missingThisObjectMarker()); // We encode the "this" value in the instruction stream, to avoid an explicit instr uction for copying or loading it. 1276 instructions().append(argv.size()); // argCount
1262 instructions().append(argv[0]->index()); // argv
1263 instructions().append(argv.size()); // argc
1264 instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFra meHeaderSize); // registerOffset 1277 instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFra meHeaderSize); // registerOffset
1265 1278
1266 if (m_shouldEmitProfileHooks) { 1279 if (m_shouldEmitProfileHooks) {
1267 emitOpcode(op_profile_did_call); 1280 emitOpcode(op_profile_did_call);
1268 instructions().append(func->index()); 1281 instructions().append(func->index());
1282
1283 if (dst == func) {
1284 thisRegister->deref();
1285 func->deref();
1286 }
1269 } 1287 }
1270 1288
1271 return dst; 1289 return dst;
1272 } 1290 }
1273 1291
1274 RegisterID* CodeGenerator::emitReturn(RegisterID* src) 1292 RegisterID* CodeGenerator::emitReturn(RegisterID* src)
1275 { 1293 {
1276 if (m_codeBlock->needsFullScopeChain) { 1294 if (m_codeBlock->needsFullScopeChain) {
1277 emitOpcode(op_tear_off_activation); 1295 emitOpcode(op_tear_off_activation);
1278 instructions().append(m_activationRegisterIndex); 1296 instructions().append(m_activationRegisterIndex);
1279 } else if (m_codeBlock->usesArguments && m_codeBlock->numParameters > 1) 1297 } else if (m_codeBlock->usesArguments && m_codeBlock->numParameters > 1)
1280 emitOpcode(op_tear_off_arguments); 1298 emitOpcode(op_tear_off_arguments);
1281 1299
1282 return emitUnaryNoDstOp(op_ret, src); 1300 return emitUnaryNoDstOp(op_ret, src);
1283 } 1301 }
1284 1302
1285 RegisterID* CodeGenerator::emitUnaryNoDstOp(OpcodeID opcode, RegisterID* src) 1303 RegisterID* CodeGenerator::emitUnaryNoDstOp(OpcodeID opcode, RegisterID* src)
1286 { 1304 {
1287 emitOpcode(opcode); 1305 emitOpcode(opcode);
1288 instructions().append(src->index()); 1306 instructions().append(src->index());
1289 return src; 1307 return src;
1290 } 1308 }
1291 1309
1292 RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, Argu mentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffs et) 1310 RegisterID* CodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, Argu mentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffs et)
1293 { 1311 {
1294 ASSERT(func->refCount()); 1312 ASSERT(func->refCount());
1295 1313
1314 if (m_shouldEmitProfileHooks) {
1315 // If codegen decided to recycle func as this call's destination registe r,
1316 // we need to undo that optimization here so that func will still be aro und
1317 // for the sake of op_profile_did_call.
1318 if (dst == func) {
1319 RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func);
1320 func = movedFunc.release().releaseRef();
1321 }
1322 }
1323
1296 RefPtr<RegisterID> funcProto = newTemporary(); 1324 RefPtr<RegisterID> funcProto = newTemporary();
1297 1325
1298 // Generate code for arguments. 1326 // Generate code for arguments.
1299 Vector<RefPtr<RegisterID>, 16> argv; 1327 Vector<RefPtr<RegisterID>, 16> argv;
1300 argv.append(newTemporary()); // reserve space for "this" 1328 argv.append(newTemporary()); // reserve space for "this"
1301 for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) { 1329 for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
1302 argv.append(newTemporary()); 1330 argv.append(newTemporary());
1303 emitNode(argv.last().get(), n); 1331 emitNode(argv.last().get(), n);
1304 } 1332 }
1305 1333
1306 if (m_shouldEmitProfileHooks) { 1334 if (m_shouldEmitProfileHooks) {
1307 emitOpcode(op_profile_will_call); 1335 emitOpcode(op_profile_will_call);
1308 instructions().append(func->index()); 1336 instructions().append(func->index());
1309 } 1337 }
1310 1338
1311 // Load prototype. 1339 // Load prototype.
1312 emitExpressionInfo(divot, startOffset, endOffset); 1340 emitExpressionInfo(divot, startOffset, endOffset);
1313 emitGetById(funcProto.get(), func, globalData()->propertyNames->prototype); 1341 emitGetById(funcProto.get(), func, globalData()->propertyNames->prototype);
1314 1342
1315 // Reserve space for call frame. 1343 // Reserve space for call frame.
1316 Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; 1344 Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1317 for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) 1345 for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1318 callFrame.append(newTemporary()); 1346 callFrame.append(newTemporary());
1319 1347
1320 emitExpressionInfo(divot, startOffset, endOffset); 1348 emitExpressionInfo(divot, startOffset, endOffset);
1321 m_codeBlock->callLinkInfos.append(CallLinkInfo()); 1349 m_codeBlock->callLinkInfos.append(CallLinkInfo());
1350
1322 emitOpcode(op_construct); 1351 emitOpcode(op_construct);
1323 instructions().append(dst->index()); 1352 instructions().append(dst->index()); // dst
1324 instructions().append(func->index()); 1353 instructions().append(func->index()); // func
1325 instructions().append(funcProto->index()); 1354 instructions().append(argv.size()); // argCount
1326 instructions().append(argv[0]->index()); // argv
1327 instructions().append(argv.size()); // argc
1328 instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFra meHeaderSize); // registerOffset 1355 instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFra meHeaderSize); // registerOffset
1356 instructions().append(funcProto->index()); // proto
1357 instructions().append(argv[0]->index()); // thisRegister
1329 1358
1330 emitOpcode(op_construct_verify); 1359 emitOpcode(op_construct_verify);
1331 instructions().append(dst->index()); 1360 instructions().append(dst->index());
1332 instructions().append(argv[0]->index()); 1361 instructions().append(argv[0]->index());
1333 1362
1334 if (m_shouldEmitProfileHooks) { 1363 if (m_shouldEmitProfileHooks) {
1335 emitOpcode(op_profile_did_call); 1364 emitOpcode(op_profile_did_call);
1336 instructions().append(func->index()); 1365 instructions().append(func->index());
1366
1367 if (dst == func)
1368 func->deref();
1337 } 1369 }
1338 1370
1339 return dst; 1371 return dst;
1340 } 1372 }
1341 1373
1342 RegisterID* CodeGenerator::emitPushScope(RegisterID* scope) 1374 RegisterID* CodeGenerator::emitPushScope(RegisterID* scope)
1343 { 1375 {
1344 ControlFlowContext context; 1376 ControlFlowContext context;
1345 context.isFinallyBlock = false; 1377 context.isFinallyBlock = false;
1346 m_scopeContextStack.append(context); 1378 m_scopeContextStack.append(context);
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 // And we could make the caller pass the node pointer in, if there was some way of getting 1738 // And we could make the caller pass the node pointer in, if there was some way of getting
1707 // that from an arbitrary node. However, calling emitExpressionInfo without any useful data 1739 // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
1708 // is still good enough to get us an accurate line number. 1740 // is still good enough to get us an accurate line number.
1709 emitExpressionInfo(0, 0, 0); 1741 emitExpressionInfo(0, 0, 0);
1710 RegisterID* exception = emitNewError(newTemporary(), SyntaxError, jsString(g lobalData(), "Expression too deep")); 1742 RegisterID* exception = emitNewError(newTemporary(), SyntaxError, jsString(g lobalData(), "Expression too deep"));
1711 emitThrow(exception); 1743 emitThrow(exception);
1712 return exception; 1744 return exception;
1713 } 1745 }
1714 1746
1715 } // namespace JSC 1747 } // namespace JSC
OLDNEW
« no previous file with comments | « third_party/WebKit/JavaScriptCore/bytecompiler/CodeGenerator.h ('k') | third_party/WebKit/JavaScriptCore/parser/Nodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698