Changeset 10207 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Aug 15, 2005, 5:47:46 PM (20 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/array_object.cpp
r10086 r10207 422 422 } 423 423 424 static ValueImp *getProperty(ExecState *exec, ObjectImp *obj, unsigned index) 425 { 426 PropertySlot slot; 427 if (!obj->getPropertySlot(exec, index, slot)) 428 return NULL; 429 return slot.getValue(exec, index); 430 } 431 424 432 // ECMA 15.4.4 425 433 ValueImp *ArrayProtoFuncImp::callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args) … … 433 441 case ToString: 434 442 435 if (!thisObj->inherits(&ArrayInstanceImp::info)) { 436 ObjectImp *err = Error::create(exec,TypeError); 437 exec->setException(err); 438 return err; 439 } 443 if (!thisObj->inherits(&ArrayInstanceImp::info)) 444 return throwError(exec, TypeError); 440 445 441 446 // fall through … … 473 478 str += static_cast<ObjectImp *>(conversionFunction)->call(exec, o, List())->toString(exec); 474 479 } else { 475 UString msg = "Can't convert " + o->className() + " object to string"; 476 ObjectImp *error = Error::create(exec, RangeError, msg.cstring().c_str()); 477 exec->setException(error); 478 return error; 480 return throwError(exec, RangeError, "Can't convert " + o->className() + " object to string"); 479 481 } 480 482 } else { … … 503 505 length = curObj->get(exec,lengthPropertyName)->toUInt32(exec); 504 506 while (k < length) { 505 ValueImp *v; 506 if (curObj->getProperty(exec, k, v)) 507 if (ValueImp *v = getProperty(exec, curObj, k)) 507 508 arr->put(exec, n, v); 508 509 n++; … … 547 548 for (unsigned int k = 0; k < middle; k++) { 548 549 unsigned lk1 = length - k - 1; 549 ValueImp *obj; 550 ValueImp *obj2; 551 bool has2 = thisObj->getProperty(exec, lk1, obj2); 552 bool has1 = thisObj->getProperty(exec, k, obj); 553 554 if (has2) 550 ValueImp *obj2 = getProperty(exec, thisObj, lk1); 551 ValueImp *obj = getProperty(exec, thisObj, k); 552 553 if (obj2) 555 554 thisObj->put(exec, k, obj2); 556 555 else 557 556 thisObj->deleteProperty(exec, k); 558 557 559 if ( has1)558 if (obj) 560 559 thisObj->put(exec, lk1, obj); 561 560 else … … 572 571 result = thisObj->get(exec, 0); 573 572 for(unsigned int k = 1; k < length; k++) { 574 ValueImp *obj; 575 if (thisObj->getProperty(exec, k, obj)) 573 if (ValueImp *obj = getProperty(exec, thisObj, k)) 576 574 thisObj->put(exec, k-1, obj); 577 575 else … … 619 617 int e = static_cast<int>(end); 620 618 for(int k = b; k < e; k++, n++) { 621 ValueImp *obj; 622 if (thisObj->getProperty(exec, k, obj)) 623 resObj->put(exec, n, obj); 619 if (ValueImp *v = getProperty(exec, thisObj, k)) 620 resObj->put(exec, n, v); 624 621 } 625 622 resObj->put(exec, lengthPropertyName, Number(n), DontEnum | DontDelete); … … 713 710 //printf( "Splicing from %d, deleteCount=%d \n", begin, deleteCount ); 714 711 for(unsigned int k = 0; k < deleteCount; k++) { 715 ValueImp *obj; 716 if (thisObj->getProperty(exec, k+begin, obj)) 717 resObj->put(exec, k, obj); 712 if (ValueImp *v = getProperty(exec, thisObj, k+begin)) 713 resObj->put(exec, k, v); 718 714 } 719 715 resObj->put(exec, lengthPropertyName, Number(deleteCount), DontEnum | DontDelete); … … 726 722 for ( unsigned int k = begin; k < length - deleteCount; ++k ) 727 723 { 728 ValueImp *obj; 729 if (thisObj->getProperty(exec, k+deleteCount, obj)) 730 thisObj->put(exec, k+additionalArgs, obj); 724 if (ValueImp *v = getProperty(exec, thisObj, k+deleteCount)) 725 thisObj->put(exec, k+additionalArgs, v); 731 726 else 732 727 thisObj->deleteProperty(exec, k+additionalArgs); … … 739 734 for ( unsigned int k = length - deleteCount; (int)k > begin; --k ) 740 735 { 741 ValueImp *obj; 742 if (thisObj->getProperty(exec, k + deleteCount - 1, obj)) 736 if (ValueImp *obj = getProperty(exec, thisObj, k + deleteCount - 1)) 743 737 thisObj->put(exec, k + additionalArgs - 1, obj); 744 738 else … … 758 752 for ( unsigned int k = length; k > 0; --k ) 759 753 { 760 ValueImp *obj; 761 if (thisObj->getProperty(exec, k - 1, obj)) 762 thisObj->put(exec, k+nrArgs-1, obj); 754 if (ValueImp *v = getProperty(exec, thisObj, k - 1)) 755 thisObj->put(exec, k+nrArgs-1, v); 763 756 else 764 757 thisObj->deleteProperty(exec, k+nrArgs-1); … … 780 773 ObjectImp *eachFunction = args[0]->toObject(exec); 781 774 782 if (!eachFunction->implementsCall()) { 783 ObjectImp *err = Error::create(exec,TypeError); 784 exec->setException(err); 785 return err; 786 } 775 if (!eachFunction->implementsCall()) 776 return throwError(exec, TypeError); 787 777 788 778 ObjectImp *applyThis = args[1]->isUndefinedOrNull() ? exec->dynamicInterpreter()->globalObject() : args[1]->toObject(exec); … … 848 838 if (args.size() == 1 && args[0]->isNumber()) { 849 839 uint32_t n = args[0]->toUInt32(exec); 850 if (n != args[0]->toNumber(exec)) { 851 ObjectImp *error = Error::create(exec, RangeError, "Array size is not a small enough positive integer."); 852 exec->setException(error); 853 return error; 854 } 840 if (n != args[0]->toNumber(exec)) 841 return throwError(exec, RangeError, "Array size is not a small enough positive integer."); 855 842 return new ArrayInstanceImp(exec->lexicalInterpreter()->builtinArrayPrototype(), n); 856 843 } -
trunk/JavaScriptCore/kjs/bool_object.cpp
r10084 r10207 79 79 { 80 80 // no generic function. "this" has to be a Boolean object 81 if (!thisObj->inherits(&BooleanInstanceImp::info)) { 82 ObjectImp *err = Error::create(exec,TypeError); 83 exec->setException(err); 84 return err; 85 } 81 if (!thisObj->inherits(&BooleanInstanceImp::info)) 82 return throwError(exec, TypeError); 86 83 87 84 // execute "toString()" or "valueOf()", respectively -
trunk/JavaScriptCore/kjs/date_object.cpp
r10137 r10207 527 527 // ToString and ValueOf are generic according to the spec, but the mozilla 528 528 // tests suggest otherwise... 529 ObjectImp *err = Error::create(exec,TypeError); 530 exec->setException(err); 531 return err; 529 return throwError(exec, TypeError); 532 530 } 533 531 -
trunk/JavaScriptCore/kjs/function.cpp
r10084 r10207 629 629 } 630 630 if (charLen == 0) { 631 if (strict) { 632 ObjectImp *error = Error::create(exec, URIError); 633 exec->setException(error); 634 return error; 635 } 631 if (strict) 632 return throwError(exec, URIError); 636 633 // The only case where we don't use "strict" mode is the "unescape" function. 637 634 // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE. … … 807 804 808 805 // no program node means a syntax occurred 809 if (!progNode) { 810 ObjectImp *err = Error::create(exec,SyntaxError,errMsg.ascii(),errLine); 811 err->put(exec,"sid",Number(sid)); 812 exec->setException(err); 813 return err; 814 } 806 if (!progNode) 807 return throwError(exec, SyntaxError, errMsg, errLine, sid, NULL); 815 808 816 809 progNode->ref(); -
trunk/JavaScriptCore/kjs/function_object.cpp
r10178 r10207 89 89 fprintf(stderr,"attempted toString() call on null or non-function object\n"); 90 90 #endif 91 ObjectImp *err = Error::create(exec,TypeError); 92 exec->setException(err); 93 return err; 91 return throwError(exec, TypeError); 94 92 } 95 93 if (thisObj->inherits(&DeclaredFunctionImp::info)) { … … 112 110 ObjectImp *func = thisObj; 113 111 114 if (!func->implementsCall()) { 115 ObjectImp *err = Error::create(exec,TypeError); 116 exec->setException(err); 117 return err; 118 } 112 if (!func->implementsCall()) 113 return throwError(exec, TypeError); 119 114 120 115 ObjectImp *applyThis; … … 135 130 applyArgs.append(argArrayObj->get(exec,i)); 136 131 } 137 else { 138 ObjectImp *err = Error::create(exec,TypeError); 139 exec->setException(err); 140 return err; 141 } 132 else 133 return throwError(exec, TypeError); 142 134 } 143 135 result = func->call(exec,applyThis,applyArgs); … … 148 140 ObjectImp *func = thisObj; 149 141 150 if (!func->implementsCall()) { 151 ObjectImp *err = Error::create(exec,TypeError); 152 exec->setException(err); 153 return err; 154 } 142 if (!func->implementsCall()) 143 return throwError(exec, TypeError); 155 144 156 145 ObjectImp *callThis; … … 223 212 224 213 // no program node == syntax error - throw a syntax error 225 if (!progNode) { 226 ObjectImp *err = Error::create(exec,SyntaxError,errMsg.ascii(),errLine); 214 if (!progNode) 227 215 // we can't return a Completion(Throw) here, so just set the exception 228 216 // and return it 229 exec->setException(err); 230 return err; 231 } 217 return throwError(exec, SyntaxError, errMsg, errLine, sid, &sourceURL); 232 218 233 219 ScopeChain scopeChain; … … 267 253 } // else error 268 254 } 269 ObjectImp *err = Error::create(exec,SyntaxError, 270 I18N_NOOP("Syntax error in parameter list"), 271 -1); 272 exec->setException(err); 273 return err; 255 return throwError(exec, SyntaxError, "Syntax error in parameter list"); 274 256 } 275 257 -
trunk/JavaScriptCore/kjs/internal.cpp
r10182 r10207 128 128 ObjectImp *UndefinedImp::toObject(ExecState *exec) const 129 129 { 130 ObjectImp *err = Error::create(exec, TypeError, I18N_NOOP("Undefined value")); 131 exec->setException(err); 132 return err; 130 return throwError(exec, TypeError, "Undefined value"); 133 131 } 134 132 … … 157 155 ObjectImp *NullImp::toObject(ExecState *exec) const 158 156 { 159 ObjectImp *err = Error::create(exec, TypeError, I18N_NOOP("Null value")); 160 exec->setException(err); 161 return err; 157 return throwError(exec, TypeError, "Null value"); 162 158 } 163 159 … … 665 661 // no program node means a syntax error occurred 666 662 if (!progNode) { 667 ObjectImp *err = Error::create(&globExec, SyntaxError, errMsg.ascii(), errLine, -1, &sourceURL); 668 err->put(&globExec, "sid", Number(sid)); 663 ObjectImp *err = Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL); 669 664 #if APPLE_CHANGES 670 665 unlockInterpreter(); … … 827 822 ValueImp *prot = get(exec,prototypePropertyName); 828 823 if (!prot->isObject() && !prot->isNull()) { 829 ObjectImp *err = Error::create(exec, TypeError, "Invalid prototype encountered " 830 "in instanceof operation."); 831 exec->setException(err); 824 throwError(exec, TypeError, "Invalid prototype encountered in instanceof operation."); 832 825 return false; 833 826 } -
trunk/JavaScriptCore/kjs/nodes.cpp
r10168 r10207 64 64 } \ 65 65 if (Collector::outOfMemory()) \ 66 return Completion(Throw, Error::create(exec, GeneralError,"Out of memory"));66 return Completion(Throw, Error::create(exec, GeneralError, "Out of memory")); 67 67 68 68 #define KJS_CHECKEXCEPTIONVALUE \ … … 136 136 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg) 137 137 { 138 ObjectImp *err = Error::create(exec, e, msg, lineNo(), sourceId(), &sourceURL); 139 exec->setException(err); 140 return err; 138 return KJS::throwError(exec, e, msg, lineNo(), sourceId(), &sourceURL); 139 } 140 141 static void substitute(UString &string, const UString &substring) 142 { 143 int position = string.find("%s"); 144 assert(position != -1); 145 string = string.substr(0, position) + substring + string.substr(position + 2); 141 146 } 142 147 143 148 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *expr) 144 149 { 145 char *vStr = strdup(v->toString(exec).ascii()); 146 char *exprStr = strdup(expr->toString().ascii()); 147 148 int length = strlen(msg) - 4 /* two %s */ + strlen(vStr) + strlen(exprStr) + 1 /* null terminator */; 149 char *str = new char[length]; 150 sprintf(str, msg, vStr, exprStr); 151 free(vStr); 152 free(exprStr); 153 154 ValueImp *result = throwError(exec, e, str); 155 delete [] str; 156 157 return result; 150 UString message = msg; 151 substitute(message, v->toString(exec)); 152 substitute(message, expr->toString()); 153 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL); 158 154 } 159 155 … … 161 157 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, Identifier label) 162 158 { 163 const char *l = label.ascii(); 164 int length = strlen(msg) - 2 /* %s */ + strlen(l) + 1 /* null terminator */; 165 char *message = new char[length]; 166 sprintf(message, msg, l); 167 168 ValueImp *result = throwError(exec, e, message); 169 delete [] message; 170 171 return result; 159 UString message = msg; 160 substitute(message, label.ustring()); 161 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL); 172 162 } 173 163 174 164 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *e1, Node *e2) 175 165 { 176 char *vStr = strdup(v->toString(exec).ascii()); 177 char *e1Str = strdup(e1->toString().ascii()); 178 char *e2Str = strdup(e2->toString().ascii()); 179 180 int length = strlen(msg) - 6 /* three %s */ + strlen(vStr) + strlen(e1Str) + strlen(e2Str) + 1 /* null terminator */; 181 char *str = new char[length]; 182 sprintf(str, msg, vStr, e1Str, e2Str); 183 free(vStr); 184 free(e1Str); 185 free(e2Str); 186 187 ValueImp *result = throwError(exec, e, str); 188 delete [] str; 189 190 return result; 166 UString message = msg; 167 substitute(message, v->toString(exec)); 168 substitute(message, e1->toString()); 169 substitute(message, e2->toString()); 170 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL); 191 171 } 192 172 193 173 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Node *expr, Identifier label) 194 174 { 195 char *vStr = strdup(v->toString(exec).ascii()); 196 char *exprStr = strdup(expr->toString().ascii()); 197 const char *l = label.ascii(); 198 int length = strlen(msg) - 6 /* three %s */ + strlen(vStr) + strlen(exprStr) + strlen(l) + 1 /* null terminator */; 199 char *message = new char[length]; 200 sprintf(message, msg, vStr, exprStr, l); 201 free(vStr); 202 free(exprStr); 203 204 ValueImp *result = throwError(exec, e, message); 205 delete [] message; 206 207 return result; 175 UString message = msg; 176 substitute(message, v->toString(exec)); 177 substitute(message, expr->toString()); 178 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL); 208 179 } 209 180 210 181 ValueImp *Node::throwError(ExecState *exec, ErrorType e, const char *msg, ValueImp *v, Identifier label) 211 182 { 212 char *vStr = strdup(v->toString(exec).ascii()); 213 const char *l = label.ascii(); 214 int length = strlen(msg) - 4 /* two %s */ + strlen(vStr) + strlen(l) + 1 /* null terminator */; 215 char *message = new char[length]; 216 sprintf(message, msg, vStr, l); 217 free(vStr); 218 219 ValueImp *result = throwError(exec, e, message); 220 delete [] message; 221 222 return result; 183 UString message = msg; 184 substitute(message, v->toString(exec)); 185 substitute(message, label.ustring()); 186 return KJS::throwError(exec, e, message, lineNo(), sourceId(), &sourceURL); 223 187 } 224 188 … … 227 191 { 228 192 if (exec->hadException()) { 229 ObjectImp *exception = exec->exception()->toObject(exec); 230 if (!exception->hasProperty(exec, "line") && 231 !exception->hasProperty(exec, "sourceURL")) { 193 ObjectImp *exception = static_cast<ObjectImp *>(exec->exception()); 194 if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) { 232 195 exception->put(exec, "line", Number(line)); 233 196 exception->put(exec, "sourceURL", String(sourceURL)); … … 236 199 } 237 200 238 239 201 // ------------------------------ StatementNode -------------------------------- 202 240 203 StatementNode::StatementNode() : l0(-1), l1(-1), sid(-1), breakPoint(false) 241 204 { … … 325 288 static ValueImp *undefinedVariableError(ExecState *exec, const Identifier &ident) 326 289 { 327 UString m = I18N_NOOP("Can't find variable: ") + ident.ustring(); 328 ObjectImp *err = Error::create(exec, ReferenceError, m.ascii()); 329 exec->setException(err); 330 return err; 290 return throwError(exec, ReferenceError, "Can't find variable: " + ident.ustring()); 331 291 } 332 292 … … 3323 3283 } 3324 3284 3325 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s) {3326 //fprintf(stderr,"ProgramNode::ProgramNode %p\n",this); 3327 } 3285 ProgramNode::ProgramNode(SourceElementsNode *s) : FunctionBodyNode(s) 3286 { 3287 } -
trunk/JavaScriptCore/kjs/number_object.cpp
r10084 r10207 129 129 { 130 130 // no generic function. "this" has to be a Number object 131 if (!thisObj->inherits(&NumberInstanceImp::info)) { 132 ObjectImp *err = Error::create(exec,TypeError); 133 exec->setException(err); 134 return err; 135 } 131 if (!thisObj->inherits(&NumberInstanceImp::info)) 132 return throwError(exec, TypeError); 136 133 137 134 ValueImp *v = thisObj->internalValue(); … … 163 160 ValueImp *fractionDigits = args[0]; 164 161 double df = fractionDigits->toInteger(exec); 165 if (!(df >= 0 && df <= 20)) { // true for NaN 166 ObjectImp *err = Error::create(exec, RangeError, 167 "toFixed() digits argument must be between 0 and 20"); 168 169 exec->setException(err); 170 return err; 171 } 162 if (!(df >= 0 && df <= 20)) // true for NaN 163 return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20"); 172 164 int f = (int)df; 173 165 … … 213 205 ValueImp *fractionDigits = args[0]; 214 206 double df = fractionDigits->toInteger(exec); 215 if (!(df >= 0 && df <= 20)) { // true for NaN 216 ObjectImp *err = Error::create(exec, RangeError, 217 "toExponential() argument must between 0 and 20"); 218 exec->setException(err); 219 return err; 220 } 207 if (!(df >= 0 && df <= 20)) // true for NaN 208 return throwError(exec, RangeError, "toExponential() argument must between 0 and 20"); 221 209 int f = (int)df; 222 210 … … 315 303 } 316 304 317 if (dp < 1 || dp > 21) { 318 ObjectImp *err = Error::create(exec, RangeError, 319 "toPrecision() argument must be between 1 and 21"); 320 exec->setException(err); 321 return err; 322 } 305 if (!(dp >= 1 && dp <= 21)) // true for NaN 306 return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21"); 323 307 int p = (int)dp; 324 308 -
trunk/JavaScriptCore/kjs/object.cpp
r10084 r10207 89 89 if (++depth > KJS_MAX_STACK) { 90 90 --depth; 91 ObjectImp *err = Error::create(exec, RangeError, 92 "Maximum call stack size exceeded."); 93 exec->setException(err); 94 return err; 91 return throwError(exec, RangeError, "Maximum call stack size exceeded."); 95 92 } 96 93 #endif … … 168 165 169 166 return Undefined(); 170 }171 172 bool ObjectImp::getProperty(ExecState *exec, const Identifier& propertyName, ValueImp*& result) const173 {174 PropertySlot slot;175 if (const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot)) {176 result = slot.getValue(exec, propertyName);177 return true;178 }179 180 return false;181 }182 183 bool ObjectImp::getProperty(ExecState *exec, unsigned propertyName, ValueImp*& result) const184 {185 PropertySlot slot;186 if (const_cast<ObjectImp *>(this)->getPropertySlot(exec, propertyName, slot)) {187 result = slot.getValue(exec, propertyName);188 return true;189 }190 191 return false;192 167 } 193 168 … … 278 253 } 279 254 280 bool ObjectImp::hasOwnProperty(ExecState *exec, const Identifier &propertyName) const281 {282 PropertySlot slot;283 return const_cast<ObjectImp *>(this)->getOwnPropertySlot(exec, propertyName, slot);284 }285 286 bool ObjectImp::hasOwnProperty(ExecState *exec, unsigned propertyName) const287 {288 PropertySlot slot;289 return const_cast<ObjectImp *>(this)->getOwnPropertySlot(exec, propertyName, slot);290 }291 292 255 // ECMA 8.6.2.5 293 256 bool ObjectImp::deleteProperty(ExecState */*exec*/, const Identifier &propertyName) … … 312 275 { 313 276 return deleteProperty(exec, Identifier::from(propertyName)); 314 }315 316 void ObjectImp::deleteAllProperties( ExecState * )317 {318 _prop.clear();319 277 } 320 278 … … 372 330 return exec->exception(); 373 331 374 ObjectImp *err = Error::create(exec, TypeError, I18N_NOOP("No default value")); 375 exec->setException(err); 376 return err; 332 return throwError(exec, TypeError, "No default value"); 377 333 } 378 334 … … 506 462 const char * const * const Error::errorNames = errorNamesArr; 507 463 508 ObjectImp *Error::create(ExecState *exec, ErrorType errtype, const char *message,509 int lineno, int sourceId, const UString *sourceURL)464 ObjectImp *Error::create(ExecState *exec, ErrorType errtype, const UString &message, 465 int lineno, int sourceId, const UString *sourceURL) 510 466 { 511 467 ObjectImp *cons; … … 534 490 } 535 491 536 if (!message)537 message = errorNames[errtype];538 492 List args; 539 args.append(String(message)); 493 if (message.isEmpty()) 494 args.append(jsString(errorNames[errtype])); 495 else 496 args.append(jsString(message)); 540 497 ObjectImp *err = static_cast<ObjectImp *>(cons->construct(exec,args)); 541 498 … … 563 520 } 564 521 565 ObjectImp *error(ExecState *exec, ErrorType type, const char *message, int line, int sourceId, const UString *sourceURL) 566 { 567 return Error::create(exec, type, message, line, sourceId, sourceURL); 522 ObjectImp *Error::create(ExecState *exec, ErrorType type, const char *message) 523 { 524 return create(exec, type, message, -1, -1, NULL); 525 } 526 527 ObjectImp *throwError(ExecState *exec, ErrorType type) 528 { 529 ObjectImp *error = Error::create(exec, type, UString(), -1, -1, NULL); 530 exec->setException(error); 531 return error; 532 } 533 534 ObjectImp *throwError(ExecState *exec, ErrorType type, const UString &message) 535 { 536 ObjectImp *error = Error::create(exec, type, message, -1, -1, NULL); 537 exec->setException(error); 538 return error; 539 } 540 541 ObjectImp *throwError(ExecState *exec, ErrorType type, const char *message) 542 { 543 ObjectImp *error = Error::create(exec, type, message, -1, -1, NULL); 544 exec->setException(error); 545 return error; 546 } 547 548 ObjectImp *throwError(ExecState *exec, ErrorType type, const UString &message, int line, int sourceId, const UString *sourceURL) 549 { 550 ObjectImp *error = Error::create(exec, type, message, line, sourceId, sourceURL); 551 exec->setException(error); 552 return error; 568 553 } 569 554 -
trunk/JavaScriptCore/kjs/object.h
r10180 r10207 91 91 92 92 /** 93 * Creates a new ObjectImp with a prototype of Null()93 * Creates a new ObjectImp with a prototype of jsNull() 94 94 * (that is, the ECMAScript "null" value, not a null object pointer). 95 *96 95 */ 97 96 ObjectImp(); 98 97 99 98 virtual void mark(); 100 101 Type type() const; 99 virtual Type type() const; 102 100 103 101 /** … … 178 176 * @return The object's prototype 179 177 */ 180 /**181 * Implementation of the [[Prototype]] internal property (implemented by182 * all Objects)183 */184 178 ValueImp *prototype() const; 185 179 void setPrototype(ValueImp *proto); … … 215 209 * @return The specified property, or Undefined 216 210 */ 217 /**218 * Implementation of the [[Get]] internal property (implemented by all219 * Objects)220 */221 // [[Get]] - must be implemented by all Objects222 211 ValueImp *get(ExecState *exec, const Identifier &propertyName) const; 223 212 ValueImp *get(ExecState *exec, unsigned propertyName) const; 224 213 225 bool getProperty(ExecState *exec, const Identifier& propertyName, ValueImp*& result) const;226 bool getProperty(ExecState *exec, unsigned propertyName, ValueImp*& result) const;227 228 214 bool getPropertySlot(ExecState *, const Identifier&, PropertySlot&); 229 215 bool getPropertySlot(ExecState *, unsigned, PropertySlot&); … … 241 227 * @param propertyValue The value to set 242 228 */ 243 /** 244 * Implementation of the [[Put]] internal property (implemented by all 245 * Objects) 246 */ 247 virtual void put(ExecState *exec, const Identifier &propertyName, 248 ValueImp *value, int attr = None); 249 virtual void put(ExecState *exec, unsigned propertyName, 250 ValueImp *value, int attr = None); 229 virtual void put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr = None); 230 virtual void put(ExecState *exec, unsigned propertyName, ValueImp *value, int attr = None); 251 231 252 232 /** … … 276 256 * @return true if the object has the property, otherwise false 277 257 */ 278 /** 279 * Implementation of the [[HasProperty]] internal property (implemented by 280 * all Objects) 281 */ 282 bool hasProperty(ExecState *exec, 283 const Identifier &propertyName) const; 258 bool hasProperty(ExecState *exec, const Identifier &propertyName) const; 284 259 bool hasProperty(ExecState *exec, unsigned propertyName) const; 285 286 /**287 * Checks to see whether the object has a property with the specified name.288 *289 * See ECMA 15.2.4.5290 *291 * @param exec The current execution state292 * @param propertyName The name of the property to check for293 * @return true if the object has the property, otherwise false294 */295 virtual bool hasOwnProperty(ExecState *exec, const Identifier &propertyName) const;296 virtual bool hasOwnProperty(ExecState *exec, unsigned propertyName) const;297 260 298 261 /** … … 307 270 * allowed. 308 271 */ 309 /** 310 * Implementation of the [[Delete]] internal property (implemented by all 311 * Objects) 312 */ 313 virtual bool deleteProperty(ExecState *exec, 314 const Identifier &propertyName); 272 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName); 315 273 virtual bool deleteProperty(ExecState *exec, unsigned propertyName); 316 317 /**318 * Remove all properties from this object.319 * This doesn't take DontDelete into account, and isn't in the ECMA spec.320 * It's simply a quick way to remove everything before destroying.321 */322 void deleteAllProperties(ExecState *);323 274 324 275 /** … … 408 359 * @return The return value from the function 409 360 */ 410 /**411 * Implementation of the [[Call]] internal property412 */413 361 ValueImp *call(ExecState *exec, ObjectImp *thisObj, const List &args); 414 362 virtual ValueImp *callAsFunction(ExecState *exec, ObjectImp *thisObj, const List &args); … … 432 380 * @return true if value delegates behavior to this object, otherwise 433 381 * false 434 */435 /**436 * Implementation of the [[HasInstance]] internal property437 382 */ 438 383 virtual bool hasInstance(ExecState *exec, ValueImp *value); … … 463 408 * @param exec The current execution state 464 409 * @return The function's scope 465 */466 /**467 * Implementation of the [[Scope]] internal property468 410 */ 469 411 const ScopeChain &scope() const { return _scope; } … … 505 447 * @param v The new internal value 506 448 */ 507 508 449 void setInternalValue(ValueImp *v); 509 450 … … 514 455 ObjectImp *toObject(ExecState *exec) const; 515 456 516 // This get method only looks at the property map. 517 // A bit like hasProperty(recursive=false), this doesn't go to the prototype. 457 // This get function only looks at the property map. 518 458 // This is used e.g. by lookupOrCreateFunction (to cache a function, we don't want 519 459 // to look up in the prototype, it might already exist there) … … 525 465 void putDirect(const Identifier &propertyName, int value, int attr = 0); 526 466 467 /** 468 * Remove all properties from this object. 469 * This doesn't take DontDelete into account, and isn't in the ECMA spec. 470 * It's simply a quick way to remove everything stored in the property map. 471 */ 472 void clearProperties() { _prop.clear(); } 473 527 474 void saveProperties(SavedProperties &p) const { _prop.save(p); } 528 475 void restoreProperties(const SavedProperties &p) { _prop.restore(p); } … … 537 484 ScopeChain _scope; 538 485 }; 539 540 // it may seem crazy to inline a function this large but it makes a big difference541 // since this is function very hot in variable lookup542 inline bool ObjectImp::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)543 {544 ObjectImp *imp = this;545 546 while (true) {547 if (imp->getOwnPropertySlot(exec, propertyName, slot))548 return true;549 550 ValueImp *proto = imp->_proto;551 if (!proto->isObject())552 break;553 554 imp = static_cast<ObjectImp *>(proto);555 }556 557 return false;558 }559 560 // it may seem crazy to inline a function this large, especially a virtual function,561 // but it makes a big difference to property lookup if subclasses can inline their562 // superclass call to this563 inline bool ObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)564 {565 ValueImp **impLocation = getDirectLocation(propertyName);566 if (impLocation) {567 slot.setValueSlot(this, impLocation);568 return true;569 }570 571 // non-standard netscape extension572 if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) {573 slot.setValueSlot(this, &_proto);574 return true;575 }576 577 return false;578 }579 486 580 487 /** … … 590 497 URIError = 6}; 591 498 592 ObjectImp *error(ExecState *exec, ErrorType type = GeneralError,593 const char *message = 0, int lineno = -1, int sourceId = -1, const UString *sourceURL = 0);594 595 499 /** 596 500 * @short Factory methods for error objects. … … 604 508 * @param errtype Type of error. 605 509 * @param message Optional error message. 606 * @param line noOptional line number.607 * @param linenoOptional source id.608 * /609 static ObjectImp *create(ExecState *exec, ErrorType errtype = GeneralError,610 const char *message = 0, int lineno = -1,611 int sourceId = -1, const UString *sourceURL = 0);510 * @param lineNumber Optional line number. 511 * @param sourceId Optional source id. 512 * @param sourceURL Optional source URL. 513 */ 514 static ObjectImp *create(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString *sourceURL); 515 static ObjectImp *create(ExecState *, ErrorType, const char *message); 612 516 613 517 /** … … 617 521 }; 618 522 523 ObjectImp *throwError(ExecState *, ErrorType, const UString &message, int lineNumber, int sourceId, const UString *sourceURL); 524 ObjectImp *throwError(ExecState *, ErrorType, const UString &message); 525 ObjectImp *throwError(ExecState *, ErrorType, const char *message); 526 ObjectImp *throwError(ExecState *, ErrorType); 527 619 528 inline bool AllocatedValueImp::isObject(const ClassInfo *info) const 620 529 { … … 662 571 } 663 572 573 // It may seem crazy to inline a function this large but it makes a big difference 574 // since this is function very hot in variable lookup 575 inline bool ObjectImp::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 576 { 577 ObjectImp *object = this; 578 while (true) { 579 if (object->getOwnPropertySlot(exec, propertyName, slot)) 580 return true; 581 582 ValueImp *proto = object->_proto; 583 if (!proto->isObject()) 584 return false; 585 586 object = static_cast<ObjectImp *>(proto); 587 } 588 } 589 590 // It may seem crazy to inline a function this large, especially a virtual function, 591 // but it makes a big difference to property lookup that derived classes can inline their 592 // base class call to this. 593 inline bool ObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) 594 { 595 if (ValueImp **location = getDirectLocation(propertyName)) { 596 slot.setValueSlot(this, location); 597 return true; 598 } 599 600 // non-standard Netscape extension 601 if (propertyName == exec->dynamicInterpreter()->specialPrototypeIdentifier()) { 602 slot.setValueSlot(this, &_proto); 603 return true; 604 } 605 606 return false; 607 } 608 664 609 } // namespace 665 610 -
trunk/JavaScriptCore/kjs/object_object.cpp
r10084 r10207 68 68 case ValueOf: 69 69 return thisObj; 70 case HasOwnProperty: 71 // Same as the in operator but without checking the prototype 72 return jsBoolean(thisObj->hasOwnProperty(exec, Identifier(args[0]->toString(exec)))); 70 case HasOwnProperty: { 71 PropertySlot slot; 72 return jsBoolean(thisObj->getOwnPropertySlot(exec, Identifier(args[0]->toString(exec)), slot)); 73 } 73 74 case ToLocaleString: 74 75 return jsString(thisObj->toString(exec)); -
trunk/JavaScriptCore/kjs/reference.cpp
r10084 r10207 70 70 ValueImp *Reference::getBase(ExecState *exec) const 71 71 { 72 if (baseIsValue) { 73 ObjectImp *err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base")); 74 exec->setException(err); 75 return err; 76 } 77 72 if (baseIsValue) 73 return throwError(exec, ReferenceError, "Invalid reference base"); 78 74 return base; 79 75 } … … 95 91 ValueImp *Reference::getValue(ExecState *exec) const 96 92 { 97 if (baseIsValue) {93 if (baseIsValue) 98 94 return base; 99 }100 95 101 96 ValueImp *o = base; 102 Type t = o ? o->type() : NullType; 103 104 if (t == NullType) { 105 UString m = I18N_NOOP("Can't find variable: ") + getPropertyName(exec).ustring(); 106 ObjectImp *err = Error::create(exec, ReferenceError, m.ascii()); 107 exec->setException(err); 108 return err; 109 } 110 111 if (t != ObjectType) { 112 UString m = I18N_NOOP("Base is not an object"); 113 ObjectImp *err = Error::create(exec, ReferenceError, m.ascii()); 114 exec->setException(err); 115 return err; 97 if (!o || !o->isObject()) { 98 if (!o || o->isNull()) 99 return throwError(exec, ReferenceError, "Can't find variable: " + getPropertyName(exec).ustring()); 100 return throwError(exec, ReferenceError, "Base is not an object"); 116 101 } 117 102 … … 124 109 { 125 110 if (baseIsValue) { 126 ObjectImp *err = Error::create(exec, ReferenceError); 127 exec->setException(err); 111 throwError(exec, ReferenceError); 128 112 return; 129 113 } … … 147 131 { 148 132 if (baseIsValue) { 149 ObjectImp *err = Error::create(exec,ReferenceError); 150 exec->setException(err); 133 throwError(exec, ReferenceError); 151 134 return false; 152 135 } -
trunk/JavaScriptCore/kjs/regexp_object.cpp
r10084 r10207 79 79 } 80 80 } 81 ObjectImp *err = Error::create(exec,TypeError); 82 exec->setException(err); 83 return err; 81 return throwError(exec, TypeError); 84 82 } 85 83 … … 255 253 ObjectImp *o = args[0]->getObject(); 256 254 if (o && o->inherits(&RegExpImp::info)) { 257 if (!args[1]->isUndefined()) { 258 ObjectImp *err = Error::create(exec,TypeError); 259 exec->setException(err); 260 return err; 261 } 255 if (!args[1]->isUndefined()) 256 return throwError(exec, TypeError); 262 257 return o; 263 258 } -
trunk/JavaScriptCore/kjs/string_object.cpp
r10084 r10207 370 370 // toString and valueOf are no generic function. 371 371 if (id == ToString || id == ValueOf) { 372 if (!thisObj || !thisObj->inherits(&StringInstanceImp::info)) { 373 ObjectImp *err = Error::create(exec,TypeError); 374 exec->setException(err); 375 return err; 376 } 372 if (!thisObj || !thisObj->inherits(&StringInstanceImp::info)) 373 return throwError(exec, TypeError); 377 374 378 375 return String(thisObj->internalValue()->toString(exec));
Note:
See TracChangeset
for help on using the changeset viewer.