1 /* 2 * Copyright (C) 1999-2002 Harri Porten (porten (at) kde.org) 3 * Copyright (C) 2001 Peter Kelly (pmk (at) post.com) 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich (at) uwaterloo.ca) 6 * Copyright (C) 2007 Maks Orlovich 7 * Copyright (C) 2007 Eric Seidel <eric (at) webkit.org> 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Library General Public 11 * License as published by the Free Software Foundation; either 12 * version 2 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Library General Public License for more details. 18 * 19 * You should have received a copy of the GNU Library General Public License 20 * along with this library; see the file COPYING.LIB. If not, write to 21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 * Boston, MA 02110-1301, USA. 23 * 24 */ 25 26 #include "config.h" 27 #include "Nodes.h" 28 #include "NodeConstructors.h" 29 30 #include "BytecodeGenerator.h" 31 #include "CallFrame.h" 32 #include "Debugger.h" 33 #include "JIT.h" 34 #include "JSFunction.h" 35 #include "JSGlobalObject.h" 36 #include "JSStaticScopeObject.h" 37 #include "LabelScope.h" 38 #include "Lexer.h" 39 #include "Operations.h" 40 #include "Parser.h" 41 #include "PropertyNameArray.h" 42 #include "RegExpObject.h" 43 #include "SamplingTool.h" 44 #include <wtf/Assertions.h> 45 #include <wtf/RefCountedLeakCounter.h> 46 #include <wtf/Threading.h> 47 48 using namespace WTF; 49 50 namespace JSC { 51 52 /* 53 Details of the emitBytecode function. 54 55 Return value: The register holding the production's value. 56 dst: An optional parameter specifying the most efficient destination at 57 which to store the production's value. The callee must honor dst. 58 59 The dst argument provides for a crude form of copy propagation. For example, 60 61 x = 1 62 63 becomes 64 65 load r[x], 1 66 67 instead of 68 69 load r0, 1 70 mov r[x], r0 71 72 because the assignment node, "x =", passes r[x] as dst to the number node, "1". 73 */ 74 75 // ------------------------------ ThrowableExpressionData -------------------------------- 76 77 static void substitute(UString& string, const UString& substring) 78 { 79 int position = string.find("%s"); 80 ASSERT(position != -1); 81 string = makeString(string.substr(0, position), substring, string.substr(position + 2)); 82 } 83 84 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message) 85 { 86 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 87 RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message)); 88 generator.emitThrow(exception); 89 return exception; 90 } 91 92 RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const UString& label) 93 { 94 UString message = messageTemplate; 95 substitute(message, label); 96 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 97 RegisterID* exception = generator.emitNewError(generator.newTemporary(), type, jsString(generator.globalData(), message)); 98 generator.emitThrow(exception); 99 return exception; 100 } 101 102 inline RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* messageTemplate, const Identifier& label) 103 { 104 return emitThrowError(generator, type, messageTemplate, label.ustring()); 105 } 106 107 // ------------------------------ NullNode ------------------------------------- 108 109 RegisterID* NullNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 110 { 111 if (dst == generator.ignoredResult()) 112 return 0; 113 return generator.emitLoad(dst, jsNull()); 114 } 115 116 // ------------------------------ BooleanNode ---------------------------------- 117 118 RegisterID* BooleanNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 119 { 120 if (dst == generator.ignoredResult()) 121 return 0; 122 return generator.emitLoad(dst, m_value); 123 } 124 125 // ------------------------------ NumberNode ----------------------------------- 126 127 RegisterID* NumberNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 128 { 129 if (dst == generator.ignoredResult()) 130 return 0; 131 return generator.emitLoad(dst, m_value); 132 } 133 134 // ------------------------------ StringNode ----------------------------------- 135 136 RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 137 { 138 if (dst == generator.ignoredResult()) 139 return 0; 140 return generator.emitLoad(dst, m_value); 141 } 142 143 // ------------------------------ RegExpNode ----------------------------------- 144 145 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 146 { 147 RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring()); 148 if (!regExp->isValid()) 149 return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage()); 150 if (dst == generator.ignoredResult()) 151 return 0; 152 return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get()); 153 } 154 155 // ------------------------------ ThisNode ------------------------------------- 156 157 RegisterID* ThisNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 158 { 159 if (dst == generator.ignoredResult()) 160 return 0; 161 return generator.moveToDestinationIfNeeded(dst, generator.thisRegister()); 162 } 163 164 // ------------------------------ ResolveNode ---------------------------------- 165 166 bool ResolveNode::isPure(BytecodeGenerator& generator) const 167 { 168 return generator.isLocal(m_ident); 169 } 170 171 RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 172 { 173 if (RegisterID* local = generator.registerFor(m_ident)) { 174 if (dst == generator.ignoredResult()) 175 return 0; 176 return generator.moveToDestinationIfNeeded(dst, local); 177 } 178 179 generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0); 180 return generator.emitResolve(generator.finalDestination(dst), m_ident); 181 } 182 183 // ------------------------------ ArrayNode ------------------------------------ 184 185 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 186 { 187 // FIXME: Should we put all of this code into emitNewArray? 188 189 unsigned length = 0; 190 ElementNode* firstPutElement; 191 for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) { 192 if (firstPutElement->elision()) 193 break; 194 ++length; 195 } 196 197 if (!firstPutElement && !m_elision) 198 return generator.emitNewArray(generator.finalDestination(dst), m_element); 199 200 RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element); 201 202 for (ElementNode* n = firstPutElement; n; n = n->next()) { 203 RegisterID* value = generator.emitNode(n->value()); 204 length += n->elision(); 205 generator.emitPutByIndex(array.get(), length++, value); 206 } 207 208 if (m_elision) { 209 RegisterID* value = generator.emitLoad(0, jsNumber(generator.globalData(), m_elision + length)); 210 generator.emitPutById(array.get(), generator.propertyNames().length, value); 211 } 212 213 return generator.moveToDestinationIfNeeded(dst, array.get()); 214 } 215 216 bool ArrayNode::isSimpleArray() const 217 { 218 if (m_elision || m_optional) 219 return false; 220 for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) { 221 if (ptr->elision()) 222 return false; 223 } 224 return true; 225 } 226 227 ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData) const 228 { 229 ASSERT(!m_elision && !m_optional); 230 ElementNode* ptr = m_element; 231 if (!ptr) 232 return 0; 233 ArgumentListNode* head = new (globalData) ArgumentListNode(globalData, ptr->value()); 234 ArgumentListNode* tail = head; 235 ptr = ptr->next(); 236 for (; ptr; ptr = ptr->next()) { 237 ASSERT(!ptr->elision()); 238 tail = new (globalData) ArgumentListNode(globalData, tail, ptr->value()); 239 } 240 return head; 241 } 242 243 // ------------------------------ ObjectLiteralNode ---------------------------- 244 245 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 246 { 247 if (!m_list) { 248 if (dst == generator.ignoredResult()) 249 return 0; 250 return generator.emitNewObject(generator.finalDestination(dst)); 251 } 252 return generator.emitNode(dst, m_list); 253 } 254 255 // ------------------------------ PropertyListNode ----------------------------- 256 257 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 258 { 259 RefPtr<RegisterID> newObj = generator.tempDestination(dst); 260 261 generator.emitNewObject(newObj.get()); 262 263 for (PropertyListNode* p = this; p; p = p->m_next) { 264 RegisterID* value = generator.emitNode(p->m_node->m_assign); 265 266 switch (p->m_node->m_type) { 267 case PropertyNode::Constant: { 268 generator.emitPutById(newObj.get(), p->m_node->name(), value); 269 break; 270 } 271 case PropertyNode::Getter: { 272 generator.emitPutGetter(newObj.get(), p->m_node->name(), value); 273 break; 274 } 275 case PropertyNode::Setter: { 276 generator.emitPutSetter(newObj.get(), p->m_node->name(), value); 277 break; 278 } 279 default: 280 ASSERT_NOT_REACHED(); 281 } 282 } 283 284 return generator.moveToDestinationIfNeeded(dst, newObj.get()); 285 } 286 287 // ------------------------------ BracketAccessorNode -------------------------------- 288 289 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 290 { 291 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator)); 292 RegisterID* property = generator.emitNode(m_subscript); 293 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 294 return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property); 295 } 296 297 // ------------------------------ DotAccessorNode -------------------------------- 298 299 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 300 { 301 RegisterID* base = generator.emitNode(m_base); 302 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 303 return generator.emitGetById(generator.finalDestination(dst), base, m_ident); 304 } 305 306 // ------------------------------ ArgumentListNode ----------------------------- 307 308 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 309 { 310 ASSERT(m_expr); 311 return generator.emitNode(dst, m_expr); 312 } 313 314 // ------------------------------ NewExprNode ---------------------------------- 315 316 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 317 { 318 RefPtr<RegisterID> func = generator.emitNode(m_expr); 319 return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args, divot(), startOffset(), endOffset()); 320 } 321 322 // ------------------------------ EvalFunctionCallNode ---------------------------------- 323 324 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 325 { 326 RefPtr<RegisterID> func = generator.tempDestination(dst); 327 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 328 generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0); 329 generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval); 330 return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 331 } 332 333 // ------------------------------ FunctionCallValueNode ---------------------------------- 334 335 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 336 { 337 RefPtr<RegisterID> func = generator.emitNode(m_expr); 338 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull()); 339 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 340 } 341 342 // ------------------------------ FunctionCallResolveNode ---------------------------------- 343 344 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 345 { 346 if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) { 347 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull()); 348 return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 349 } 350 351 int index = 0; 352 size_t depth = 0; 353 JSObject* globalObject = 0; 354 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) { 355 RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject); 356 RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull()); 357 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 358 } 359 360 RefPtr<RegisterID> func = generator.newTemporary(); 361 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 362 int identifierStart = divot() - startOffset(); 363 generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0); 364 generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident); 365 return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 366 } 367 368 // ------------------------------ FunctionCallBracketNode ---------------------------------- 369 370 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 371 { 372 RefPtr<RegisterID> base = generator.emitNode(m_base); 373 RegisterID* property = generator.emitNode(m_subscript); 374 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 375 RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property); 376 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get()); 377 return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 378 } 379 380 // ------------------------------ FunctionCallDotNode ---------------------------------- 381 382 RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 383 { 384 RefPtr<RegisterID> function = generator.tempDestination(dst); 385 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 386 generator.emitNode(thisRegister.get(), m_base); 387 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 388 generator.emitMethodCheck(); 389 generator.emitGetById(function.get(), thisRegister.get(), m_ident); 390 return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 391 } 392 393 RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 394 { 395 RefPtr<Label> realCall = generator.newLabel(); 396 RefPtr<Label> end = generator.newLabel(); 397 RefPtr<RegisterID> base = generator.emitNode(m_base); 398 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 399 RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); 400 RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get()); 401 generator.emitJumpIfNotFunctionCall(function.get(), realCall.get()); 402 { 403 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get()); 404 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 405 ArgumentListNode* oldList = m_args->m_listNode; 406 if (m_args->m_listNode && m_args->m_listNode->m_expr) { 407 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr); 408 m_args->m_listNode = m_args->m_listNode->m_next; 409 } else 410 generator.emitLoad(thisRegister.get(), jsNull()); 411 412 generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 413 generator.emitJump(end.get()); 414 m_args->m_listNode = oldList; 415 } 416 generator.emitLabel(realCall.get()); 417 { 418 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get()); 419 generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 420 } 421 generator.emitLabel(end.get()); 422 return finalDestination.get(); 423 } 424 425 static bool areTrivialApplyArguments(ArgumentsNode* args) 426 { 427 return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next 428 || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray()); 429 } 430 431 RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 432 { 433 // A few simple cases can be trivially handled as ordinary function calls. 434 // function.apply(), function.apply(arg) -> identical to function.call 435 // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation 436 bool mayBeCall = areTrivialApplyArguments(m_args); 437 438 RefPtr<Label> realCall = generator.newLabel(); 439 RefPtr<Label> end = generator.newLabel(); 440 RefPtr<RegisterID> base = generator.emitNode(m_base); 441 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 442 RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); 443 RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get()); 444 generator.emitJumpIfNotFunctionApply(function.get(), realCall.get()); 445 { 446 if (mayBeCall) { 447 RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get()); 448 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 449 ArgumentListNode* oldList = m_args->m_listNode; 450 if (m_args->m_listNode && m_args->m_listNode->m_expr) { 451 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr); 452 m_args->m_listNode = m_args->m_listNode->m_next; 453 if (m_args->m_listNode) { 454 ASSERT(m_args->m_listNode->m_expr->isSimpleArray()); 455 ASSERT(!m_args->m_listNode->m_next); 456 m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr)->toArgumentList(generator.globalData()); 457 } 458 } else 459 generator.emitLoad(thisRegister.get(), jsNull()); 460 generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 461 m_args->m_listNode = oldList; 462 } else { 463 ASSERT(m_args->m_listNode && m_args->m_listNode->m_next); 464 RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get()); 465 RefPtr<RegisterID> argsCountRegister = generator.newTemporary(); 466 RefPtr<RegisterID> thisRegister = generator.newTemporary(); 467 RefPtr<RegisterID> argsRegister = generator.newTemporary(); 468 generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr); 469 ArgumentListNode* args = m_args->m_listNode->m_next; 470 bool isArgumentsApply = false; 471 if (args->m_expr->isResolveNode()) { 472 ResolveNode* resolveNode = static_cast<ResolveNode*>(args->m_expr); 473 isArgumentsApply = generator.willResolveToArguments(resolveNode->identifier()); 474 if (isArgumentsApply) 475 generator.emitMove(argsRegister.get(), generator.uncheckedRegisterForArguments()); 476 } 477 if (!isArgumentsApply) 478 generator.emitNode(argsRegister.get(), args->m_expr); 479 while ((args = args->m_next)) 480 generator.emitNode(args->m_expr); 481 482 generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get()); 483 generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset()); 484 } 485 generator.emitJump(end.get()); 486 } 487 generator.emitLabel(realCall.get()); 488 { 489 RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get()); 490 generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset()); 491 } 492 generator.emitLabel(end.get()); 493 return finalDestination.get(); 494 } 495 496 // ------------------------------ PostfixResolveNode ---------------------------------- 497 498 static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper) 499 { 500 return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst); 501 } 502 503 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper) 504 { 505 if (srcDst == dst) 506 return generator.emitToJSNumber(dst, srcDst); 507 return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst); 508 } 509 510 RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 511 { 512 if (RegisterID* local = generator.registerFor(m_ident)) { 513 if (generator.isLocalConstant(m_ident)) { 514 if (dst == generator.ignoredResult()) 515 return 0; 516 return generator.emitToJSNumber(generator.finalDestination(dst), local); 517 } 518 519 if (dst == generator.ignoredResult()) 520 return emitPreIncOrDec(generator, local, m_operator); 521 return emitPostIncOrDec(generator, generator.finalDestination(dst), local, m_operator); 522 } 523 524 int index = 0; 525 size_t depth = 0; 526 JSObject* globalObject = 0; 527 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) { 528 RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject); 529 RegisterID* oldValue; 530 if (dst == generator.ignoredResult()) { 531 oldValue = 0; 532 emitPreIncOrDec(generator, value.get(), m_operator); 533 } else { 534 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator); 535 } 536 generator.emitPutScopedVar(depth, index, value.get(), globalObject); 537 return oldValue; 538 } 539 540 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 541 RefPtr<RegisterID> value = generator.newTemporary(); 542 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident); 543 RegisterID* oldValue; 544 if (dst == generator.ignoredResult()) { 545 oldValue = 0; 546 emitPreIncOrDec(generator, value.get(), m_operator); 547 } else { 548 oldValue = emitPostIncOrDec(generator, generator.finalDestination(dst), value.get(), m_operator); 549 } 550 generator.emitPutById(base.get(), m_ident, value.get()); 551 return oldValue; 552 } 553 554 // ------------------------------ PostfixBracketNode ---------------------------------- 555 556 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 557 { 558 RefPtr<RegisterID> base = generator.emitNode(m_base); 559 RefPtr<RegisterID> property = generator.emitNode(m_subscript); 560 561 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 562 RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get()); 563 RegisterID* oldValue; 564 if (dst == generator.ignoredResult()) { 565 oldValue = 0; 566 if (m_operator == OpPlusPlus) 567 generator.emitPreInc(value.get()); 568 else 569 generator.emitPreDec(value.get()); 570 } else { 571 oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get()); 572 } 573 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 574 generator.emitPutByVal(base.get(), property.get(), value.get()); 575 return oldValue; 576 } 577 578 // ------------------------------ PostfixDotNode ---------------------------------- 579 580 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 581 { 582 RefPtr<RegisterID> base = generator.emitNode(m_base); 583 584 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 585 RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident); 586 RegisterID* oldValue; 587 if (dst == generator.ignoredResult()) { 588 oldValue = 0; 589 if (m_operator == OpPlusPlus) 590 generator.emitPreInc(value.get()); 591 else 592 generator.emitPreDec(value.get()); 593 } else { 594 oldValue = (m_operator == OpPlusPlus) ? generator.emitPostInc(generator.finalDestination(dst), value.get()) : generator.emitPostDec(generator.finalDestination(dst), value.get()); 595 } 596 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 597 generator.emitPutById(base.get(), m_ident, value.get()); 598 return oldValue; 599 } 600 601 // ------------------------------ PostfixErrorNode ----------------------------------- 602 603 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 604 { 605 return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus 606 ? "Postfix ++ operator applied to value that is not a reference." 607 : "Postfix -- operator applied to value that is not a reference."); 608 } 609 610 // ------------------------------ DeleteResolveNode ----------------------------------- 611 612 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 613 { 614 if (generator.registerFor(m_ident)) 615 return generator.emitLoad(generator.finalDestination(dst), false); 616 617 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 618 RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident); 619 return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident); 620 } 621 622 // ------------------------------ DeleteBracketNode ----------------------------------- 623 624 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 625 { 626 RefPtr<RegisterID> r0 = generator.emitNode(m_base); 627 RegisterID* r1 = generator.emitNode(m_subscript); 628 629 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 630 return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1); 631 } 632 633 // ------------------------------ DeleteDotNode ----------------------------------- 634 635 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 636 { 637 RegisterID* r0 = generator.emitNode(m_base); 638 639 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 640 return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident); 641 } 642 643 // ------------------------------ DeleteValueNode ----------------------------------- 644 645 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 646 { 647 generator.emitNode(generator.ignoredResult(), m_expr); 648 649 // delete on a non-location expression ignores the value and returns true 650 return generator.emitLoad(generator.finalDestination(dst), true); 651 } 652 653 // ------------------------------ VoidNode ------------------------------------- 654 655 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 656 { 657 if (dst == generator.ignoredResult()) { 658 generator.emitNode(generator.ignoredResult(), m_expr); 659 return 0; 660 } 661 RefPtr<RegisterID> r0 = generator.emitNode(m_expr); 662 return generator.emitLoad(dst, jsUndefined()); 663 } 664 665 // ------------------------------ TypeOfValueNode ----------------------------------- 666 667 RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 668 { 669 if (RegisterID* local = generator.registerFor(m_ident)) { 670 if (dst == generator.ignoredResult()) 671 return 0; 672 return generator.emitTypeOf(generator.finalDestination(dst), local); 673 } 674 675 RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident); 676 generator.emitGetById(scratch.get(), scratch.get(), m_ident); 677 if (dst == generator.ignoredResult()) 678 return 0; 679 return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get()); 680 } 681 682 // ------------------------------ TypeOfValueNode ----------------------------------- 683 684 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 685 { 686 if (dst == generator.ignoredResult()) { 687 generator.emitNode(generator.ignoredResult(), m_expr); 688 return 0; 689 } 690 RefPtr<RegisterID> src = generator.emitNode(m_expr); 691 return generator.emitTypeOf(generator.finalDestination(dst), src.get()); 692 } 693 694 // ------------------------------ PrefixResolveNode ---------------------------------- 695 696 RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 697 { 698 if (RegisterID* local = generator.registerFor(m_ident)) { 699 if (generator.isLocalConstant(m_ident)) { 700 if (dst == generator.ignoredResult()) 701 return 0; 702 RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0); 703 return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes()); 704 } 705 706 emitPreIncOrDec(generator, local, m_operator); 707 return generator.moveToDestinationIfNeeded(dst, local); 708 } 709 710 int index = 0; 711 size_t depth = 0; 712 JSObject* globalObject = 0; 713 if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) { 714 RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject); 715 emitPreIncOrDec(generator, propDst.get(), m_operator); 716 generator.emitPutScopedVar(depth, index, propDst.get(), globalObject); 717 return generator.moveToDestinationIfNeeded(dst, propDst.get()); 718 } 719 720 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 721 RefPtr<RegisterID> propDst = generator.tempDestination(dst); 722 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident); 723 emitPreIncOrDec(generator, propDst.get(), m_operator); 724 generator.emitPutById(base.get(), m_ident, propDst.get()); 725 return generator.moveToDestinationIfNeeded(dst, propDst.get()); 726 } 727 728 // ------------------------------ PrefixBracketNode ---------------------------------- 729 730 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 731 { 732 RefPtr<RegisterID> base = generator.emitNode(m_base); 733 RefPtr<RegisterID> property = generator.emitNode(m_subscript); 734 RefPtr<RegisterID> propDst = generator.tempDestination(dst); 735 736 generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset); 737 RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get()); 738 if (m_operator == OpPlusPlus) 739 generator.emitPreInc(value); 740 else 741 generator.emitPreDec(value); 742 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 743 generator.emitPutByVal(base.get(), property.get(), value); 744 return generator.moveToDestinationIfNeeded(dst, propDst.get()); 745 } 746 747 // ------------------------------ PrefixDotNode ---------------------------------- 748 749 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 750 { 751 RefPtr<RegisterID> base = generator.emitNode(m_base); 752 RefPtr<RegisterID> propDst = generator.tempDestination(dst); 753 754 generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset); 755 RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident); 756 if (m_operator == OpPlusPlus) 757 generator.emitPreInc(value); 758 else 759 generator.emitPreDec(value); 760 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 761 generator.emitPutById(base.get(), m_ident, value); 762 return generator.moveToDestinationIfNeeded(dst, propDst.get()); 763 } 764 765 // ------------------------------ PrefixErrorNode ----------------------------------- 766 767 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 768 { 769 return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus 770 ? "Prefix ++ operator applied to value that is not a reference." 771 : "Prefix -- operator applied to value that is not a reference."); 772 } 773 774 // ------------------------------ Unary Operation Nodes ----------------------------------- 775 776 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 777 { 778 RegisterID* src = generator.emitNode(m_expr); 779 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src); 780 } 781 782 783 // ------------------------------ LogicalNotNode ----------------------------------- 784 785 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue) 786 { 787 ASSERT(expr()->hasConditionContextCodegen()); 788 789 // reverse the true and false targets 790 generator.emitNodeInConditionContext(expr(), falseTarget, trueTarget, !fallThroughMeansTrue); 791 } 792 793 794 // ------------------------------ Binary Operation Nodes ----------------------------------- 795 796 // BinaryOpNode::emitStrcat: 797 // 798 // This node generates an op_strcat operation. This opcode can handle concatenation of three or 799 // more values, where we can determine a set of separate op_add operations would be operating on 800 // string values. 801 // 802 // This function expects to be operating on a graph of AST nodes looking something like this: 803 // 804 // (a)... (b) 805 // \ / 806 // (+) (c) 807 // \ / 808 // [d] ((+)) 809 // \ / 810 // [+=] 811 // 812 // The assignment operation is optional, if it exists the register holding the value on the 813 // lefthand side of the assignment should be passing as the optional 'lhs' argument. 814 // 815 // The method should be called on the node at the root of the tree of regular binary add 816 // operations (marked in the diagram with a double set of parentheses). This node must 817 // be performing a string concatenation (determined by statically detecting that at least 818 // one child must be a string). 819 // 820 // Since the minimum number of values being concatenated together is expected to be 3, if 821 // a lhs to a concatenating assignment is not provided then the root add should have at 822 // least one left child that is also an add that can be determined to be operating on strings. 823 // 824 RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe) 825 { 826 ASSERT(isAdd()); 827 ASSERT(resultDescriptor().definitelyIsString()); 828 829 // Create a list of expressions for all the adds in the tree of nodes we can convert into 830 // a string concatenation. The rightmost node (c) is added first. The rightmost node is 831 // added first, and the leftmost child is never added, so the vector produced for the 832 // example above will be [ c, b ]. 833 Vector<ExpressionNode*, 16> reverseExpressionList; 834 reverseExpressionList.append(m_expr2); 835 836 // Examine the left child of the add. So long as this is a string add, add its right-child 837 // to the list, and keep processing along the left fork. 838 ExpressionNode* leftMostAddChild = m_expr1; 839 while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) { 840 reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2); 841 leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1; 842 } 843 844 Vector<RefPtr<RegisterID>, 16> temporaryRegisters; 845 846 // If there is an assignment, allocate a temporary to hold the lhs after conversion. 847 // We could possibly avoid this (the lhs is converted last anyway, we could let the 848 // op_strcat node handle its conversion if required). 849 if (lhs) 850 temporaryRegisters.append(generator.newTemporary()); 851 852 // Emit code for the leftmost node ((a) in the example). 853 temporaryRegisters.append(generator.newTemporary()); 854 RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get(); 855 generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild); 856 857 // Note on ordering of conversions: 858 // 859 // We maintain the same ordering of conversions as we would see if the concatenations 860 // was performed as a sequence of adds (otherwise this optimization could change 861 // behaviour should an object have been provided a valueOf or toString method). 862 // 863 // Considering the above example, the sequnce of execution is: 864 // * evaluate operand (a) 865 // * evaluate operand (b) 866 // * convert (a) to primitive <- (this would be triggered by the first add) 867 // * convert (b) to primitive <- (ditto) 868 // * evaluate operand (c) 869 // * convert (c) to primitive <- (this would be triggered by the second add) 870 // And optionally, if there is an assignment: 871 // * convert (d) to primitive <- (this would be triggered by the assigning addition) 872 // 873 // As such we do not plant an op to convert the leftmost child now. Instead, use 874 // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion 875 // once the second node has been generated. However, if the leftmost child is an 876 // immediate we can trivially determine that no conversion will be required. 877 // If this is the case 878 if (leftMostAddChild->isString()) 879 leftMostAddChildTempRegister = 0; 880 881 while (reverseExpressionList.size()) { 882 ExpressionNode* node = reverseExpressionList.last(); 883 reverseExpressionList.removeLast(); 884 885 // Emit the code for the current node. 886 temporaryRegisters.append(generator.newTemporary()); 887 generator.emitNode(temporaryRegisters.last().get(), node); 888 889 // On the first iteration of this loop, when we first reach this point we have just 890 // generated the second node, which means it is time to convert the leftmost operand. 891 if (leftMostAddChildTempRegister) { 892 generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister); 893 leftMostAddChildTempRegister = 0; // Only do this once. 894 } 895 // Plant a conversion for this node, if necessary. 896 if (!node->isString()) 897 generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get()); 898 } 899 ASSERT(temporaryRegisters.size() >= 3); 900 901 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated. 902 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now. 903 if (emitExpressionInfoForMe) 904 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset()); 905 906 // If there is an assignment convert the lhs now. This will also copy lhs to 907 // the temporary register we allocated for it. 908 if (lhs) 909 generator.emitToPrimitive(temporaryRegisters[0].get(), lhs); 910 911 return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size()); 912 } 913 914 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 915 { 916 OpcodeID opcodeID = this->opcodeID(); 917 918 if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString()) 919 return emitStrcat(generator, dst); 920 921 if (opcodeID == op_neq) { 922 if (m_expr1->isNull() || m_expr2->isNull()) { 923 RefPtr<RegisterID> src = generator.tempDestination(dst); 924 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1); 925 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get()); 926 } 927 } 928 929 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 930 RegisterID* src2 = generator.emitNode(m_expr2); 931 return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor())); 932 } 933 934 RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 935 { 936 if (m_expr1->isNull() || m_expr2->isNull()) { 937 RefPtr<RegisterID> src = generator.tempDestination(dst); 938 generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1); 939 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get()); 940 } 941 942 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 943 RegisterID* src2 = generator.emitNode(m_expr2); 944 return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2); 945 } 946 947 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 948 { 949 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 950 RegisterID* src2 = generator.emitNode(m_expr2); 951 return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2); 952 } 953 954 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 955 { 956 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 957 RegisterID* src2 = generator.emitNode(m_expr2); 958 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor())); 959 } 960 961 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 962 { 963 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 964 RegisterID* src2 = generator.emitNode(m_expr2); 965 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 966 return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor())); 967 } 968 969 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 970 { 971 RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator)); 972 RefPtr<RegisterID> src2 = generator.emitNode(m_expr2); 973 974 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 975 generator.emitGetByIdExceptionInfo(op_instanceof); 976 RegisterID* src2Prototype = generator.emitGetById(generator.newTemporary(), src2.get(), generator.globalData()->propertyNames->prototype); 977 978 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 979 return generator.emitInstanceOf(generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), src2Prototype); 980 } 981 982 // ------------------------------ LogicalOpNode ---------------------------- 983 984 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 985 { 986 RefPtr<RegisterID> temp = generator.tempDestination(dst); 987 RefPtr<Label> target = generator.newLabel(); 988 989 generator.emitNode(temp.get(), m_expr1); 990 if (m_operator == OpLogicalAnd) 991 generator.emitJumpIfFalse(temp.get(), target.get()); 992 else 993 generator.emitJumpIfTrue(temp.get(), target.get()); 994 generator.emitNode(temp.get(), m_expr2); 995 generator.emitLabel(target.get()); 996 997 return generator.moveToDestinationIfNeeded(dst, temp.get()); 998 } 999 1000 void LogicalOpNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue) 1001 { 1002 if (m_expr1->hasConditionContextCodegen()) { 1003 RefPtr<Label> afterExpr1 = generator.newLabel(); 1004 if (m_operator == OpLogicalAnd) 1005 generator.emitNodeInConditionContext(m_expr1, afterExpr1.get(), falseTarget, true); 1006 else 1007 generator.emitNodeInConditionContext(m_expr1, trueTarget, afterExpr1.get(), false); 1008 generator.emitLabel(afterExpr1.get()); 1009 } else { 1010 RegisterID* temp = generator.emitNode(m_expr1); 1011 if (m_operator == OpLogicalAnd) 1012 generator.emitJumpIfFalse(temp, falseTarget); 1013 else 1014 generator.emitJumpIfTrue(temp, trueTarget); 1015 } 1016 1017 if (m_expr2->hasConditionContextCodegen()) 1018 generator.emitNodeInConditionContext(m_expr2, trueTarget, falseTarget, fallThroughMeansTrue); 1019 else { 1020 RegisterID* temp = generator.emitNode(m_expr2); 1021 if (fallThroughMeansTrue) 1022 generator.emitJumpIfFalse(temp, falseTarget); 1023 else 1024 generator.emitJumpIfTrue(temp, trueTarget); 1025 } 1026 } 1027 1028 // ------------------------------ ConditionalNode ------------------------------ 1029 1030 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1031 { 1032 RefPtr<RegisterID> newDst = generator.finalDestination(dst); 1033 RefPtr<Label> beforeElse = generator.newLabel(); 1034 RefPtr<Label> afterElse = generator.newLabel(); 1035 1036 if (m_logical->hasConditionContextCodegen()) { 1037 RefPtr<Label> beforeThen = generator.newLabel(); 1038 generator.emitNodeInConditionContext(m_logical, beforeThen.get(), beforeElse.get(), true); 1039 generator.emitLabel(beforeThen.get()); 1040 } else { 1041 RegisterID* cond = generator.emitNode(m_logical); 1042 generator.emitJumpIfFalse(cond, beforeElse.get()); 1043 } 1044 1045 generator.emitNode(newDst.get(), m_expr1); 1046 generator.emitJump(afterElse.get()); 1047 1048 generator.emitLabel(beforeElse.get()); 1049 generator.emitNode(newDst.get(), m_expr2); 1050 1051 generator.emitLabel(afterElse.get()); 1052 1053 return newDst.get(); 1054 } 1055 1056 // ------------------------------ ReadModifyResolveNode ----------------------------------- 1057 1058 // FIXME: should this be moved to be a method on BytecodeGenerator? 1059 static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0) 1060 { 1061 OpcodeID opcodeID; 1062 switch (oper) { 1063 case OpMultEq: 1064 opcodeID = op_mul; 1065 break; 1066 case OpDivEq: 1067 opcodeID = op_div; 1068 break; 1069 case OpPlusEq: 1070 if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString()) 1071 return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe); 1072 opcodeID = op_add; 1073 break; 1074 case OpMinusEq: 1075 opcodeID = op_sub; 1076 break; 1077 case OpLShift: 1078 opcodeID = op_lshift; 1079 break; 1080 case OpRShift: 1081 opcodeID = op_rshift; 1082 break; 1083 case OpURShift: 1084 opcodeID = op_urshift; 1085 break; 1086 case OpAndEq: 1087 opcodeID = op_bitand; 1088 break; 1089 case OpXOrEq: 1090 opcodeID = op_bitxor; 1091 break; 1092 case OpOrEq: 1093 opcodeID = op_bitor; 1094 break; 1095 case OpModEq: 1096 opcodeID = op_mod; 1097 break; 1098 default: 1099 ASSERT_NOT_REACHED(); 1100 return dst; 1101 } 1102 1103 RegisterID* src2 = generator.emitNode(m_right); 1104 1105 // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated. 1106 // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now. 1107 if (emitExpressionInfoForMe) 1108 generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset()); 1109 1110 return generator.emitBinaryOp(opcodeID, dst, src1, src2, types); 1111 } 1112 1113 RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1114 { 1115 if (RegisterID* local = generator.registerFor(m_ident)) { 1116 if (generator.isLocalConstant(m_ident)) { 1117 return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1118 } 1119 1120 if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) { 1121 RefPtr<RegisterID> result = generator.newTemporary(); 1122 generator.emitMove(result.get(), local); 1123 emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1124 generator.emitMove(local, result.get()); 1125 return generator.moveToDestinationIfNeeded(dst, result.get()); 1126 } 1127 1128 RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1129 return generator.moveToDestinationIfNeeded(dst, result); 1130 } 1131 1132 int index = 0; 1133 size_t depth = 0; 1134 JSObject* globalObject = 0; 1135 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) { 1136 RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject); 1137 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1138 generator.emitPutScopedVar(depth, index, result, globalObject); 1139 return result; 1140 } 1141 1142 RefPtr<RegisterID> src1 = generator.tempDestination(dst); 1143 generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0); 1144 RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident); 1145 RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this); 1146 return generator.emitPutById(base.get(), m_ident, result); 1147 } 1148 1149 // ------------------------------ AssignResolveNode ----------------------------------- 1150 1151 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1152 { 1153 if (RegisterID* local = generator.registerFor(m_ident)) { 1154 if (generator.isLocalConstant(m_ident)) 1155 return generator.emitNode(dst, m_right); 1156 1157 RegisterID* result = generator.emitNode(local, m_right); 1158 return generator.moveToDestinationIfNeeded(dst, result); 1159 } 1160 1161 int index = 0; 1162 size_t depth = 0; 1163 JSObject* globalObject = 0; 1164 if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) { 1165 if (dst == generator.ignoredResult()) 1166 dst = 0; 1167 RegisterID* value = generator.emitNode(dst, m_right); 1168 generator.emitPutScopedVar(depth, index, value, globalObject); 1169 return value; 1170 } 1171 1172 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident); 1173 if (dst == generator.ignoredResult()) 1174 dst = 0; 1175 RegisterID* value = generator.emitNode(dst, m_right); 1176 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1177 return generator.emitPutById(base.get(), m_ident, value); 1178 } 1179 1180 // ------------------------------ AssignDotNode ----------------------------------- 1181 1182 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1183 { 1184 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator)); 1185 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst); 1186 RegisterID* result = generator.emitNode(value.get(), m_right); 1187 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1188 generator.emitPutById(base.get(), m_ident, result); 1189 return generator.moveToDestinationIfNeeded(dst, result); 1190 } 1191 1192 // ------------------------------ ReadModifyDotNode ----------------------------------- 1193 1194 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1195 { 1196 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator)); 1197 1198 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 1199 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); 1200 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1201 1202 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1203 return generator.emitPutById(base.get(), m_ident, updatedValue); 1204 } 1205 1206 // ------------------------------ AssignErrorNode ----------------------------------- 1207 1208 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1209 { 1210 return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference."); 1211 } 1212 1213 // ------------------------------ AssignBracketNode ----------------------------------- 1214 1215 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1216 { 1217 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator)); 1218 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator)); 1219 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst); 1220 RegisterID* result = generator.emitNode(value.get(), m_right); 1221 1222 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1223 generator.emitPutByVal(base.get(), property.get(), result); 1224 return generator.moveToDestinationIfNeeded(dst, result); 1225 } 1226 1227 // ------------------------------ ReadModifyBracketNode ----------------------------------- 1228 1229 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1230 { 1231 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator)); 1232 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator)); 1233 1234 generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset); 1235 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get()); 1236 RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor())); 1237 1238 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1239 generator.emitPutByVal(base.get(), property.get(), updatedValue); 1240 1241 return updatedValue; 1242 } 1243 1244 // ------------------------------ CommaNode ------------------------------------ 1245 1246 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1247 { 1248 ASSERT(m_expressions.size() > 1); 1249 for (size_t i = 0; i < m_expressions.size() - 1; i++) 1250 generator.emitNode(generator.ignoredResult(), m_expressions[i]); 1251 return generator.emitNode(dst, m_expressions.last()); 1252 } 1253 1254 // ------------------------------ ConstDeclNode ------------------------------------ 1255 1256 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator) 1257 { 1258 if (RegisterID* local = generator.constRegisterFor(m_ident)) { 1259 if (!m_init) 1260 return local; 1261 1262 return generator.emitNode(local, m_init); 1263 } 1264 1265 if (generator.codeType() != EvalCode) { 1266 if (m_init) 1267 return generator.emitNode(m_init); 1268 else 1269 return generator.emitResolve(generator.newTemporary(), m_ident); 1270 } 1271 // FIXME: While this code should only be hit in eval code, it will potentially 1272 // assign to the wrong base if m_ident exists in an intervening dynamic scope. 1273 RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident); 1274 RegisterID* value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined()); 1275 return generator.emitPutById(base.get(), m_ident, value); 1276 } 1277 1278 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1279 { 1280 RegisterID* result = 0; 1281 for (ConstDeclNode* n = this; n; n = n->m_next) 1282 result = n->emitCodeSingle(generator); 1283 1284 return result; 1285 } 1286 1287 // ------------------------------ ConstStatementNode ----------------------------- 1288 1289 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1290 { 1291 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1292 return generator.emitNode(m_next); 1293 } 1294 1295 // ------------------------------ SourceElements ------------------------------- 1296 1297 1298 inline StatementNode* SourceElements::lastStatement() const 1299 { 1300 size_t size = m_statements.size(); 1301 return size ? m_statements[size - 1] : 0; 1302 } 1303 1304 inline void SourceElements::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1305 { 1306 size_t size = m_statements.size(); 1307 for (size_t i = 0; i < size; ++i) 1308 generator.emitNode(dst, m_statements[i]); 1309 } 1310 1311 // ------------------------------ BlockNode ------------------------------------ 1312 1313 inline StatementNode* BlockNode::lastStatement() const 1314 { 1315 return m_statements ? m_statements->lastStatement() : 0; 1316 } 1317 1318 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1319 { 1320 if (m_statements) 1321 m_statements->emitBytecode(generator, dst); 1322 return 0; 1323 } 1324 1325 // ------------------------------ EmptyStatementNode --------------------------- 1326 1327 RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1328 { 1329 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1330 return dst; 1331 } 1332 1333 // ------------------------------ DebuggerStatementNode --------------------------- 1334 1335 RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1336 { 1337 generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine()); 1338 return dst; 1339 } 1340 1341 // ------------------------------ ExprStatementNode ---------------------------- 1342 1343 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1344 { 1345 ASSERT(m_expr); 1346 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1347 return generator.emitNode(dst, m_expr); 1348 } 1349 1350 // ------------------------------ VarStatementNode ---------------------------- 1351 1352 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1353 { 1354 ASSERT(m_expr); 1355 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1356 return generator.emitNode(m_expr); 1357 } 1358 1359 // ------------------------------ IfNode --------------------------------------- 1360 1361 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1362 { 1363 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1364 1365 RefPtr<Label> afterThen = generator.newLabel(); 1366 1367 if (m_condition->hasConditionContextCodegen()) { 1368 RefPtr<Label> beforeThen = generator.newLabel(); 1369 generator.emitNodeInConditionContext(m_condition, beforeThen.get(), afterThen.get(), true); 1370 generator.emitLabel(beforeThen.get()); 1371 } else { 1372 RegisterID* cond = generator.emitNode(m_condition); 1373 generator.emitJumpIfFalse(cond, afterThen.get()); 1374 } 1375 1376 generator.emitNode(dst, m_ifBlock); 1377 generator.emitLabel(afterThen.get()); 1378 1379 // FIXME: This should return the last statement executed so that it can be returned as a Completion. 1380 return 0; 1381 } 1382 1383 // ------------------------------ IfElseNode --------------------------------------- 1384 1385 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1386 { 1387 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1388 1389 RefPtr<Label> beforeElse = generator.newLabel(); 1390 RefPtr<Label> afterElse = generator.newLabel(); 1391 1392 if (m_condition->hasConditionContextCodegen()) { 1393 RefPtr<Label> beforeThen = generator.newLabel(); 1394 generator.emitNodeInConditionContext(m_condition, beforeThen.get(), beforeElse.get(), true); 1395 generator.emitLabel(beforeThen.get()); 1396 } else { 1397 RegisterID* cond = generator.emitNode(m_condition); 1398 generator.emitJumpIfFalse(cond, beforeElse.get()); 1399 } 1400 1401 generator.emitNode(dst, m_ifBlock); 1402 generator.emitJump(afterElse.get()); 1403 1404 generator.emitLabel(beforeElse.get()); 1405 1406 generator.emitNode(dst, m_elseBlock); 1407 1408 generator.emitLabel(afterElse.get()); 1409 1410 // FIXME: This should return the last statement executed so that it can be returned as a Completion. 1411 return 0; 1412 } 1413 1414 // ------------------------------ DoWhileNode ---------------------------------- 1415 1416 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1417 { 1418 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); 1419 1420 RefPtr<Label> topOfLoop = generator.newLabel(); 1421 generator.emitLabel(topOfLoop.get()); 1422 1423 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1424 1425 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement); 1426 1427 generator.emitLabel(scope->continueTarget()); 1428 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo()); 1429 if (m_expr->hasConditionContextCodegen()) 1430 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false); 1431 else { 1432 RegisterID* cond = generator.emitNode(m_expr); 1433 generator.emitJumpIfTrue(cond, topOfLoop.get()); 1434 } 1435 1436 generator.emitLabel(scope->breakTarget()); 1437 return result.get(); 1438 } 1439 1440 // ------------------------------ WhileNode ------------------------------------ 1441 1442 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1443 { 1444 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); 1445 1446 generator.emitJump(scope->continueTarget()); 1447 1448 RefPtr<Label> topOfLoop = generator.newLabel(); 1449 generator.emitLabel(topOfLoop.get()); 1450 1451 generator.emitNode(dst, m_statement); 1452 1453 generator.emitLabel(scope->continueTarget()); 1454 generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo()); 1455 1456 if (m_expr->hasConditionContextCodegen()) 1457 generator.emitNodeInConditionContext(m_expr, topOfLoop.get(), scope->breakTarget(), false); 1458 else { 1459 RegisterID* cond = generator.emitNode(m_expr); 1460 generator.emitJumpIfTrue(cond, topOfLoop.get()); 1461 } 1462 1463 generator.emitLabel(scope->breakTarget()); 1464 1465 // FIXME: This should return the last statement executed so that it can be returned as a Completion 1466 return 0; 1467 } 1468 1469 // ------------------------------ ForNode -------------------------------------- 1470 1471 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1472 { 1473 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); 1474 1475 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1476 1477 if (m_expr1) 1478 generator.emitNode(generator.ignoredResult(), m_expr1); 1479 1480 RefPtr<Label> condition = generator.newLabel(); 1481 generator.emitJump(condition.get()); 1482 1483 RefPtr<Label> topOfLoop = generator.newLabel(); 1484 generator.emitLabel(topOfLoop.get()); 1485 1486 RefPtr<RegisterID> result = generator.emitNode(dst, m_statement); 1487 1488 generator.emitLabel(scope->continueTarget()); 1489 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1490 if (m_expr3) 1491 generator.emitNode(generator.ignoredResult(), m_expr3); 1492 1493 generator.emitLabel(condition.get()); 1494 if (m_expr2) { 1495 if (m_expr2->hasConditionContextCodegen()) 1496 generator.emitNodeInConditionContext(m_expr2, topOfLoop.get(), scope->breakTarget(), false); 1497 else { 1498 RegisterID* cond = generator.emitNode(m_expr2); 1499 generator.emitJumpIfTrue(cond, topOfLoop.get()); 1500 } 1501 } else 1502 generator.emitJump(topOfLoop.get()); 1503 1504 generator.emitLabel(scope->breakTarget()); 1505 return result.get(); 1506 } 1507 1508 // ------------------------------ ForInNode ------------------------------------ 1509 1510 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1511 { 1512 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop); 1513 1514 if (!m_lexpr->isLocation()) 1515 return emitThrowError(generator, ReferenceError, "Left side of for-in statement is not a reference."); 1516 1517 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1518 1519 if (m_init) 1520 generator.emitNode(generator.ignoredResult(), m_init); 1521 1522 RefPtr<RegisterID> base = generator.newTemporary(); 1523 generator.emitNode(base.get(), m_expr); 1524 RefPtr<RegisterID> i = generator.newTemporary(); 1525 RefPtr<RegisterID> size = generator.newTemporary(); 1526 RefPtr<RegisterID> expectedSubscript; 1527 RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), base.get(), i.get(), size.get(), scope->breakTarget()); 1528 generator.emitJump(scope->continueTarget()); 1529 1530 RefPtr<Label> loopStart = generator.newLabel(); 1531 generator.emitLabel(loopStart.get()); 1532 1533 RegisterID* propertyName; 1534 bool optimizedForinAccess = false; 1535 if (m_lexpr->isResolveNode()) { 1536 const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier(); 1537 propertyName = generator.registerFor(ident); 1538 if (!propertyName) { 1539 propertyName = generator.newTemporary(); 1540 RefPtr<RegisterID> protect = propertyName; 1541 RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident); 1542 1543 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1544 generator.emitPutById(base, ident, propertyName); 1545 } else { 1546 expectedSubscript = generator.emitMove(generator.newTemporary(), propertyName); 1547 generator.pushOptimisedForIn(expectedSubscript.get(), iter.get(), i.get(), propertyName); 1548 optimizedForinAccess = true; 1549 } 1550 } else if (m_lexpr->isDotAccessorNode()) { 1551 DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr); 1552 const Identifier& ident = assignNode->identifier(); 1553 propertyName = generator.newTemporary(); 1554 RefPtr<RegisterID> protect = propertyName; 1555 RegisterID* base = generator.emitNode(assignNode->base()); 1556 1557 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset()); 1558 generator.emitPutById(base, ident, propertyName); 1559 } else { 1560 ASSERT(m_lexpr->isBracketAccessorNode()); 1561 BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr); 1562 propertyName = generator.newTemporary(); 1563 RefPtr<RegisterID> protect = propertyName; 1564 RefPtr<RegisterID> base = generator.emitNode(assignNode->base()); 1565 RegisterID* subscript = generator.emitNode(assignNode->subscript()); 1566 1567 generator.emitExpressionInfo(assignNode->divot(), assignNode->startOffset(), assignNode->endOffset()); 1568 generator.emitPutByVal(base.get(), subscript, propertyName); 1569 } 1570 1571 generator.emitNode(dst, m_statement); 1572 1573 if (optimizedForinAccess) 1574 generator.popOptimisedForIn(); 1575 1576 generator.emitLabel(scope->continueTarget()); 1577 generator.emitNextPropertyName(propertyName, base.get(), i.get(), size.get(), iter.get(), loopStart.get()); 1578 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1579 generator.emitLabel(scope->breakTarget()); 1580 return dst; 1581 } 1582 1583 // ------------------------------ ContinueNode --------------------------------- 1584 1585 // ECMA 12.7 1586 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1587 { 1588 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1589 1590 LabelScope* scope = generator.continueTarget(m_ident); 1591 1592 if (!scope) 1593 return m_ident.isEmpty() 1594 ? emitThrowError(generator, SyntaxError, "Invalid continue statement.") 1595 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident); 1596 1597 generator.emitJumpScopes(scope->continueTarget(), scope->scopeDepth()); 1598 return dst; 1599 } 1600 1601 // ------------------------------ BreakNode ------------------------------------ 1602 1603 // ECMA 12.8 1604 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1605 { 1606 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1607 1608 LabelScope* scope = generator.breakTarget(m_ident); 1609 1610 if (!scope) 1611 return m_ident.isEmpty() 1612 ? emitThrowError(generator, SyntaxError, "Invalid break statement.") 1613 : emitThrowError(generator, SyntaxError, "Undefined label: '%s'.", m_ident); 1614 1615 generator.emitJumpScopes(scope->breakTarget(), scope->scopeDepth()); 1616 return dst; 1617 } 1618 1619 // ------------------------------ ReturnNode ----------------------------------- 1620 1621 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1622 { 1623 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1624 if (generator.codeType() != FunctionCode) 1625 return emitThrowError(generator, SyntaxError, "Invalid return statement."); 1626 1627 if (dst == generator.ignoredResult()) 1628 dst = 0; 1629 RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined()); 1630 RefPtr<RegisterID> returnRegister; 1631 if (generator.scopeDepth()) { 1632 RefPtr<Label> l0 = generator.newLabel(); 1633 if (generator.hasFinaliser() && !r0->isTemporary()) { 1634 returnRegister = generator.emitMove(generator.newTemporary(), r0); 1635 r0 = returnRegister.get(); 1636 } 1637 generator.emitJumpScopes(l0.get(), 0); 1638 generator.emitLabel(l0.get()); 1639 } 1640 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine()); 1641 return generator.emitReturn(r0); 1642 } 1643 1644 // ------------------------------ WithNode ------------------------------------- 1645 1646 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1647 { 1648 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1649 1650 RefPtr<RegisterID> scope = generator.newTemporary(); 1651 generator.emitNode(scope.get(), m_expr); // scope must be protected until popped 1652 generator.emitExpressionInfo(m_divot, m_expressionLength, 0); 1653 generator.emitPushScope(scope.get()); 1654 RegisterID* result = generator.emitNode(dst, m_statement); 1655 generator.emitPopScope(); 1656 return result; 1657 } 1658 1659 // ------------------------------ CaseClauseNode -------------------------------- 1660 1661 inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1662 { 1663 if (m_statements) 1664 m_statements->emitBytecode(generator, dst); 1665 } 1666 1667 // ------------------------------ CaseBlockNode -------------------------------- 1668 1669 enum SwitchKind { 1670 SwitchUnset = 0, 1671 SwitchNumber = 1, 1672 SwitchString = 2, 1673 SwitchNeither = 3 1674 }; 1675 1676 static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& literalVector, SwitchKind& typeForTable, bool& singleCharacterSwitch, int32_t& min_num, int32_t& max_num) 1677 { 1678 for (; list; list = list->getNext()) { 1679 ExpressionNode* clauseExpression = list->getClause()->expr(); 1680 literalVector.append(clauseExpression); 1681 if (clauseExpression->isNumber()) { 1682 double value = static_cast<NumberNode*>(clauseExpression)->value(); 1683 int32_t intVal = static_cast<int32_t>(value); 1684 if ((typeForTable & ~SwitchNumber) || (intVal != value)) { 1685 typeForTable = SwitchNeither; 1686 break; 1687 } 1688 if (intVal < min_num) 1689 min_num = intVal; 1690 if (intVal > max_num) 1691 max_num = intVal; 1692 typeForTable = SwitchNumber; 1693 continue; 1694 } 1695 if (clauseExpression->isString()) { 1696 if (typeForTable & ~SwitchString) { 1697 typeForTable = SwitchNeither; 1698 break; 1699 } 1700 const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring(); 1701 if (singleCharacterSwitch &= value.size() == 1) { 1702 int32_t intVal = value.rep()->data()[0]; 1703 if (intVal < min_num) 1704 min_num = intVal; 1705 if (intVal > max_num) 1706 max_num = intVal; 1707 } 1708 typeForTable = SwitchString; 1709 continue; 1710 } 1711 typeForTable = SwitchNeither; 1712 break; 1713 } 1714 } 1715 1716 SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num) 1717 { 1718 SwitchKind typeForTable = SwitchUnset; 1719 bool singleCharacterSwitch = true; 1720 1721 processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num); 1722 processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num); 1723 1724 if (typeForTable == SwitchUnset || typeForTable == SwitchNeither) 1725 return SwitchInfo::SwitchNone; 1726 1727 if (typeForTable == SwitchNumber) { 1728 int32_t range = max_num - min_num; 1729 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10) 1730 return SwitchInfo::SwitchImmediate; 1731 return SwitchInfo::SwitchNone; 1732 } 1733 1734 ASSERT(typeForTable == SwitchString); 1735 1736 if (singleCharacterSwitch) { 1737 int32_t range = max_num - min_num; 1738 if (min_num <= max_num && range <= 1000 && (range / literalVector.size()) < 10) 1739 return SwitchInfo::SwitchCharacter; 1740 } 1741 1742 return SwitchInfo::SwitchString; 1743 } 1744 1745 RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst) 1746 { 1747 RefPtr<Label> defaultLabel; 1748 Vector<RefPtr<Label>, 8> labelVector; 1749 Vector<ExpressionNode*, 8> literalVector; 1750 int32_t min_num = std::numeric_limits<int32_t>::max(); 1751 int32_t max_num = std::numeric_limits<int32_t>::min(); 1752 SwitchInfo::SwitchType switchType = tryOptimizedSwitch(literalVector, min_num, max_num); 1753 1754 if (switchType != SwitchInfo::SwitchNone) { 1755 // Prepare the various labels 1756 for (uint32_t i = 0; i < literalVector.size(); i++) 1757 labelVector.append(generator.newLabel()); 1758 defaultLabel = generator.newLabel(); 1759 generator.beginSwitch(switchExpression, switchType); 1760 } else { 1761 // Setup jumps 1762 for (ClauseListNode* list = m_list1; list; list = list->getNext()) { 1763 RefPtr<RegisterID> clauseVal = generator.newTemporary(); 1764 generator.emitNode(clauseVal.get(), list->getClause()->expr()); 1765 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes()); 1766 labelVector.append(generator.newLabel()); 1767 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get()); 1768 } 1769 1770 for (ClauseListNode* list = m_list2; list; list = list->getNext()) { 1771 RefPtr<RegisterID> clauseVal = generator.newTemporary(); 1772 generator.emitNode(clauseVal.get(), list->getClause()->expr()); 1773 generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes()); 1774 labelVector.append(generator.newLabel()); 1775 generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get()); 1776 } 1777 defaultLabel = generator.newLabel(); 1778 generator.emitJump(defaultLabel.get()); 1779 } 1780 1781 RegisterID* result = 0; 1782 1783 size_t i = 0; 1784 for (ClauseListNode* list = m_list1; list; list = list->getNext()) { 1785 generator.emitLabel(labelVector[i++].get()); 1786 list->getClause()->emitBytecode(generator, dst); 1787 } 1788 1789 if (m_defaultClause) { 1790 generator.emitLabel(defaultLabel.get()); 1791 m_defaultClause->emitBytecode(generator, dst); 1792 } 1793 1794 for (ClauseListNode* list = m_list2; list; list = list->getNext()) { 1795 generator.emitLabel(labelVector[i++].get()); 1796 list->getClause()->emitBytecode(generator, dst); 1797 } 1798 if (!m_defaultClause) 1799 generator.emitLabel(defaultLabel.get()); 1800 1801 ASSERT(i == labelVector.size()); 1802 if (switchType != SwitchInfo::SwitchNone) { 1803 ASSERT(labelVector.size() == literalVector.size()); 1804 generator.endSwitch(labelVector.size(), labelVector.data(), literalVector.data(), defaultLabel.get(), min_num, max_num); 1805 } 1806 return result; 1807 } 1808 1809 // ------------------------------ SwitchNode ----------------------------------- 1810 1811 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1812 { 1813 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1814 1815 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch); 1816 1817 RefPtr<RegisterID> r0 = generator.emitNode(m_expr); 1818 RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst); 1819 1820 generator.emitLabel(scope->breakTarget()); 1821 return r1; 1822 } 1823 1824 // ------------------------------ LabelNode ------------------------------------ 1825 1826 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1827 { 1828 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1829 1830 if (generator.breakTarget(m_name)) 1831 return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name); 1832 1833 RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name); 1834 RegisterID* r0 = generator.emitNode(dst, m_statement); 1835 1836 generator.emitLabel(scope->breakTarget()); 1837 return r0; 1838 } 1839 1840 // ------------------------------ ThrowNode ------------------------------------ 1841 1842 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1843 { 1844 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1845 1846 if (dst == generator.ignoredResult()) 1847 dst = 0; 1848 RefPtr<RegisterID> expr = generator.emitNode(m_expr); 1849 generator.emitExpressionInfo(divot(), startOffset(), endOffset()); 1850 generator.emitThrow(expr.get()); 1851 return 0; 1852 } 1853 1854 // ------------------------------ TryNode -------------------------------------- 1855 1856 RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1857 { 1858 // NOTE: The catch and finally blocks must be labeled explicitly, so the 1859 // optimizer knows they may be jumped to from anywhere. 1860 1861 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1862 1863 RefPtr<Label> tryStartLabel = generator.newLabel(); 1864 RefPtr<Label> finallyStart; 1865 RefPtr<RegisterID> finallyReturnAddr; 1866 if (m_finallyBlock) { 1867 finallyStart = generator.newLabel(); 1868 finallyReturnAddr = generator.newTemporary(); 1869 generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get()); 1870 } 1871 1872 generator.emitLabel(tryStartLabel.get()); 1873 generator.emitNode(dst, m_tryBlock); 1874 1875 if (m_catchBlock) { 1876 RefPtr<Label> catchEndLabel = generator.newLabel(); 1877 1878 // Normal path: jump over the catch block. 1879 generator.emitJump(catchEndLabel.get()); 1880 1881 // Uncaught exception path: the catch block. 1882 RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); 1883 RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get()); 1884 if (m_catchHasEval) { 1885 RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary()); 1886 generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get()); 1887 generator.emitMove(exceptionRegister.get(), dynamicScopeObject.get()); 1888 generator.emitPushScope(exceptionRegister.get()); 1889 } else 1890 generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get()); 1891 generator.emitNode(dst, m_catchBlock); 1892 generator.emitPopScope(); 1893 generator.emitLabel(catchEndLabel.get()); 1894 } 1895 1896 if (m_finallyBlock) { 1897 generator.popFinallyContext(); 1898 // there may be important registers live at the time we jump 1899 // to a finally block (such as for a return or throw) so we 1900 // ref the highest register ever used as a conservative 1901 // approach to not clobbering anything important 1902 RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister(); 1903 RefPtr<Label> finallyEndLabel = generator.newLabel(); 1904 1905 // Normal path: invoke the finally block, then jump over it. 1906 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get()); 1907 generator.emitJump(finallyEndLabel.get()); 1908 1909 // Uncaught exception path: invoke the finally block, then re-throw the exception. 1910 RefPtr<Label> here = generator.emitLabel(generator.newLabel().get()); 1911 RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get()); 1912 generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get()); 1913 generator.emitThrow(tempExceptionRegister.get()); 1914 1915 // The finally block. 1916 generator.emitLabel(finallyStart.get()); 1917 generator.emitNode(dst, m_finallyBlock); 1918 generator.emitSubroutineReturn(finallyReturnAddr.get()); 1919 1920 generator.emitLabel(finallyEndLabel.get()); 1921 } 1922 1923 return dst; 1924 } 1925 1926 // ------------------------------ ScopeNode ----------------------------- 1927 1928 inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst) 1929 { 1930 if (m_data->m_statements) 1931 m_data->m_statements->emitBytecode(generator, dst); 1932 } 1933 1934 // ------------------------------ ProgramNode ----------------------------- 1935 1936 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1937 { 1938 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine()); 1939 1940 RefPtr<RegisterID> dstRegister = generator.newTemporary(); 1941 generator.emitLoad(dstRegister.get(), jsUndefined()); 1942 emitStatementsBytecode(generator, dstRegister.get()); 1943 1944 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine()); 1945 generator.emitEnd(dstRegister.get()); 1946 return 0; 1947 } 1948 1949 // ------------------------------ EvalNode ----------------------------- 1950 1951 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1952 { 1953 generator.emitDebugHook(WillExecuteProgram, firstLine(), lastLine()); 1954 1955 RefPtr<RegisterID> dstRegister = generator.newTemporary(); 1956 generator.emitLoad(dstRegister.get(), jsUndefined()); 1957 emitStatementsBytecode(generator, dstRegister.get()); 1958 1959 generator.emitDebugHook(DidExecuteProgram, firstLine(), lastLine()); 1960 generator.emitEnd(dstRegister.get()); 1961 return 0; 1962 } 1963 1964 // ------------------------------ FunctionBodyNode ----------------------------- 1965 1966 RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1967 { 1968 generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine()); 1969 emitStatementsBytecode(generator, generator.ignoredResult()); 1970 StatementNode* singleStatement = this->singleStatement(); 1971 if (singleStatement && singleStatement->isBlock()) { 1972 StatementNode* lastStatementInBlock = static_cast<BlockNode*>(singleStatement)->lastStatement(); 1973 if (lastStatementInBlock && lastStatementInBlock->isReturnNode()) 1974 return 0; 1975 } 1976 1977 RegisterID* r0 = generator.emitLoad(0, jsUndefined()); 1978 generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine()); 1979 generator.emitReturn(r0); 1980 return 0; 1981 } 1982 1983 // ------------------------------ FuncDeclNode --------------------------------- 1984 1985 RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1986 { 1987 if (dst == generator.ignoredResult()) 1988 dst = 0; 1989 return dst; 1990 } 1991 1992 // ------------------------------ FuncExprNode --------------------------------- 1993 1994 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1995 { 1996 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this); 1997 } 1998 1999 } // namespace JSC 2000