1/* 2* Copyright (C) 1999-2002 Harri Porten (porten@kde.org) 3* Copyright (C) 2001 Peter Kelly (pmk@post.com) 4* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 5* Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) 6* Copyright (C) 2007 Maks Orlovich 7* Copyright (C) 2007 Eric Seidel <eric@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 48using namespace WTF; 49 50namespace 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 77static 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 84RegisterID* 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 92RegisterID* 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 102inline 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 109RegisterID* 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 118RegisterID* 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 127RegisterID* 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 136RegisterID* 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 145RegisterID* 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 157RegisterID* 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 166bool ResolveNode::isPure(BytecodeGenerator& generator) const 167{ 168 return generator.isLocal(m_ident); 169} 170 171RegisterID* 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 185RegisterID* 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 216bool 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 227ArgumentListNode* 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 245RegisterID* 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 257RegisterID* 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 289RegisterID* 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 299RegisterID* 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 308RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 309{ 310 ASSERT(m_expr); 311 return generator.emitNode(dst, m_expr); 312} 313 314// ------------------------------ NewExprNode ---------------------------------- 315 316RegisterID* 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 324RegisterID* 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 335RegisterID* 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 344RegisterID* 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 370RegisterID* 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 382RegisterID* 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 393RegisterID* 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 425static 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 431RegisterID* 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 498static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* srcDst, Operator oper) 499{ 500 return (oper == OpPlusPlus) ? generator.emitPreInc(srcDst) : generator.emitPreDec(srcDst); 501} 502 503static 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 510RegisterID* 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 556RegisterID* 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 580RegisterID* 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 603RegisterID* 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 612RegisterID* 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 624RegisterID* 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 635RegisterID* 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 645RegisterID* 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 655RegisterID* 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 667RegisterID* 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 684RegisterID* 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 696RegisterID* 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 730RegisterID* 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 749RegisterID* 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 767RegisterID* 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 776RegisterID* 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 785void 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// 824RegisterID* 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 914RegisterID* 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 934RegisterID* 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 947RegisterID* 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 954RegisterID* 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 961RegisterID* 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 969RegisterID* 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 984RegisterID* 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 1000void 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 1030RegisterID* 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? 1059static 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 1113RegisterID* 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 1151RegisterID* 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 1182RegisterID* 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 1194RegisterID* 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 1208RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1209{ 1210 return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference."); 1211} 1212 1213// ------------------------------ AssignBracketNode ----------------------------------- 1214 1215RegisterID* 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 1229RegisterID* 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 1246RegisterID* 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 1256RegisterID* 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 1278RegisterID* 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 1289RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) 1290{ 1291 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1292 return generator.emitNode(m_next); 1293} 1294 1295// ------------------------------ SourceElements ------------------------------- 1296 1297 1298inline StatementNode* SourceElements::lastStatement() const 1299{ 1300 size_t size = m_statements.size(); 1301 return size ? m_statements[size - 1] : 0; 1302} 1303 1304inline 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 1313inline StatementNode* BlockNode::lastStatement() const 1314{ 1315 return m_statements ? m_statements->lastStatement() : 0; 1316} 1317 1318RegisterID* 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 1327RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1328{ 1329 generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 1330 return dst; 1331} 1332 1333// ------------------------------ DebuggerStatementNode --------------------------- 1334 1335RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1336{ 1337 generator.emitDebugHook(DidReachBreakpoint, firstLine(), lastLine()); 1338 return dst; 1339} 1340 1341// ------------------------------ ExprStatementNode ---------------------------- 1342 1343RegisterID* 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 1352RegisterID* 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 1361RegisterID* 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 1385RegisterID* 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 1416RegisterID* 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 1442RegisterID* 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 1471RegisterID* 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 1510RegisterID* 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 1586RegisterID* 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 1604RegisterID* 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 1621RegisterID* 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 1646RegisterID* 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 1661inline void CaseClauseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1662{ 1663 if (m_statements) 1664 m_statements->emitBytecode(generator, dst); 1665} 1666 1667// ------------------------------ CaseBlockNode -------------------------------- 1668 1669enum SwitchKind { 1670 SwitchUnset = 0, 1671 SwitchNumber = 1, 1672 SwitchString = 2, 1673 SwitchNeither = 3 1674}; 1675 1676static 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 1716SwitchInfo::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 1745RegisterID* 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 1811RegisterID* 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 1826RegisterID* 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 1842RegisterID* 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 1856RegisterID* 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 1928inline 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 1936RegisterID* 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 1951RegisterID* 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 1966RegisterID* 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 1985RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1986{ 1987 if (dst == generator.ignoredResult()) 1988 dst = 0; 1989 return dst; 1990} 1991 1992// ------------------------------ FuncExprNode --------------------------------- 1993 1994RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) 1995{ 1996 return generator.emitNewFunctionExpression(generator.finalDestination(dst), this); 1997} 1998 1999} // namespace JSC 2000