Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 // const $Function = global.Function; | 34 // const $Function = global.Function; |
| 35 // const $Array = global.Array; | 35 // const $Array = global.Array; |
| 36 // const $NaN = 0/0; | 36 // const $NaN = 0/0; |
| 37 // | 37 // |
| 38 // in math.js: | 38 // in math.js: |
| 39 // const $floor = MathFloor | 39 // const $floor = MathFloor |
| 40 | 40 |
| 41 const $isNaN = GlobalIsNaN; | 41 const $isNaN = GlobalIsNaN; |
| 42 const $isFinite = GlobalIsFinite; | 42 const $isFinite = GlobalIsFinite; |
| 43 | 43 |
| 44 | |
| 44 // ---------------------------------------------------------------------------- | 45 // ---------------------------------------------------------------------------- |
| 45 | 46 |
| 46 | 47 |
| 47 // Helper function used to install functions on objects. | 48 // Helper function used to install functions on objects. |
| 48 function InstallFunctions(object, attributes, functions) { | 49 function InstallFunctions(object, attributes, functions) { |
| 49 if (functions.length >= 8) { | 50 if (functions.length >= 8) { |
| 50 %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1); | 51 %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1); |
| 51 } | 52 } |
| 52 for (var i = 0; i < functions.length; i += 2) { | 53 for (var i = 0; i < functions.length; i += 2) { |
| 53 var key = functions[i]; | 54 var key = functions[i]; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 } | 274 } |
| 274 | 275 |
| 275 | 276 |
| 276 function ObjectKeys(obj) { | 277 function ObjectKeys(obj) { |
| 277 if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj)) | 278 if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj)) |
| 278 throw MakeTypeError('object_keys_non_object', [obj]); | 279 throw MakeTypeError('object_keys_non_object', [obj]); |
| 279 return %LocalKeys(obj); | 280 return %LocalKeys(obj); |
| 280 } | 281 } |
| 281 | 282 |
| 282 | 283 |
| 284 // ES5 8.10.1. | |
| 285 function IsAccessorDescriptor(desc) { | |
| 286 if (IS_UNDEFINED(desc)) return false; | |
| 287 return desc.getSet_ || desc.setSet_; | |
| 288 } | |
| 289 | |
| 290 | |
| 291 // ES5 8.10.2. | |
| 292 function IsDataDescriptor(desc) { | |
| 293 if (IS_UNDEFINED(desc)) return false; | |
| 294 return desc.valueSet_ || desc.writableSet_; | |
| 295 } | |
| 296 | |
| 297 | |
| 298 // ES5 8.10.3. | |
| 299 function IsGenericDescriptor(desc) { | |
| 300 return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc)); | |
| 301 } | |
| 302 | |
| 303 | |
| 304 function IsInconsistentDescriptor(desc) { | |
| 305 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); | |
| 306 } | |
| 307 | |
| 308 | |
| 309 // ES5 8.10.5. | |
| 310 function ToPropertyDescriptor(obj) { | |
| 311 if (!IS_OBJECT(obj)) { | |
| 312 throw MakeTypeError(property_desc_object, [obj]); | |
| 313 } | |
| 314 var desc = new PropertyDescriptor(); | |
| 315 | |
| 316 var enumerable = obj.enumerable; | |
| 317 if (!IS_UNDEFINED(enumerable) || "enumerable" in obj) { | |
| 318 desc.setEnumerable(ToBoolean(enumerable)); | |
| 319 } | |
| 320 | |
| 321 var configurable = obj.configurable; | |
| 322 if (!IS_UNDEFINED(configurable) || "configurable" in obj) { | |
| 323 desc.setConfigurable(ToBoolean(configurable)); | |
| 324 } | |
| 325 | |
| 326 var value = obj.value; | |
| 327 if (value !== void 0 || value in obj) desc.setValue(value); | |
|
Christian Plesner Hansen
2009/12/08 20:44:40
IS_UNDEFINED
| |
| 328 | |
| 329 var writable = obj.writable; | |
| 330 if (!IS_UNDEFINED(writable) || "writable" in obj) { | |
| 331 desc.setWritable(ToBoolean(writable)); | |
| 332 } | |
| 333 | |
| 334 var get = obj.get; | |
| 335 if (!IS_UNDEFINED(get) || "get" in obj) { | |
| 336 if (!IS_UNDEFINED(get) && !IS_FUNCTION(get)) { | |
| 337 throw MakeTypeError("getter_must_be_callable", [get]); | |
| 338 } | |
| 339 desc.setGet(get); | |
| 340 } | |
| 341 | |
| 342 var set = obj.set; | |
| 343 if (!IS_UNDEFINED(set) || "set" in obj) { | |
| 344 if (set !== void 0 && !IS_FUNCTION(set)) { | |
|
Christian Plesner Hansen
2009/12/08 20:44:40
IS_UNDEFINED
| |
| 345 throw MakeTypeError("setter_must_be_callable", [set]); | |
| 346 } | |
| 347 desc.setSet(set); | |
| 348 } | |
| 349 | |
| 350 if (IsInconsistentDescriptor(desc)) { | |
| 351 throw MakeTypeError("value_and_getter_setter", [obj]); | |
| 352 } | |
| 353 return desc; | |
| 354 } | |
| 355 | |
| 356 | |
| 357 function PropertyDescriptor() { | |
| 358 // Initialize here so they are all in-object and have the same map. | |
| 359 // Default values from ES5 8.6.1. | |
| 360 this.value_ = void 0; | |
| 361 this.valueSet_ = false; | |
| 362 this.writable_ = false; | |
| 363 this.writableSet_ = false; | |
| 364 this.enumerable_ = false; | |
| 365 this.configurable_ = false; | |
| 366 this.get_ = void 0; | |
| 367 this.getSet_ = false; | |
|
Christian Plesner Hansen
2009/12/08 20:44:40
Calling a boolean xxxSet is not a particularly obv
| |
| 368 this.set_ = void 0; | |
| 369 this.setSet_ = false; | |
| 370 } | |
| 371 | |
| 372 | |
| 373 PropertyDescriptor.prototype.setValue = function(value) { | |
| 374 this.value_ = value; | |
| 375 this.valueSet_ = true; | |
| 376 } | |
| 377 | |
| 378 | |
| 379 PropertyDescriptor.prototype.getValue = function() { | |
| 380 return this.value_; | |
| 381 } | |
| 382 | |
| 383 | |
| 384 PropertyDescriptor.prototype.setEnumerable = function(enumerable) { | |
| 385 this.enumerable_ = enumerable; | |
| 386 } | |
| 387 | |
| 388 | |
| 389 PropertyDescriptor.prototype.isEnumerable = function () { | |
| 390 return this.enumerable_; | |
| 391 } | |
| 392 | |
| 393 | |
| 394 PropertyDescriptor.prototype.setWritable = function(writable) { | |
| 395 this.writable_ = writable; | |
| 396 this.writableSet_ = true; | |
| 397 } | |
| 398 | |
| 399 | |
| 400 PropertyDescriptor.prototype.isWritable = function() { | |
| 401 return this.writable_; | |
| 402 } | |
| 403 | |
| 404 | |
| 405 PropertyDescriptor.prototype.setConfigurable = function(configurable) { | |
| 406 this.configurable_ = configurable; | |
| 407 } | |
| 408 | |
| 409 | |
| 410 PropertyDescriptor.prototype.isConfigurable = function() { | |
| 411 return this.configurable_; | |
| 412 } | |
| 413 | |
| 414 | |
| 415 PropertyDescriptor.prototype.setGet = function(get) { | |
| 416 this.get_ = get; | |
| 417 this.getSet_ = true; | |
| 418 } | |
| 419 | |
| 420 | |
| 421 PropertyDescriptor.prototype.getGet = function() { | |
| 422 return this.get_; | |
| 423 } | |
| 424 | |
| 425 | |
| 426 PropertyDescriptor.prototype.setSet = function(set) { | |
| 427 this.set_ = set; | |
| 428 this.setSet_ = true; | |
| 429 } | |
| 430 | |
| 431 | |
| 432 PropertyDescriptor.prototype.getSet = function() { | |
| 433 return this.set_; | |
| 434 } | |
| 435 | |
| 436 | |
| 437 // ES5 8.12.9. This version cannot cope with the property p already | |
| 438 // being present on obj. | |
| 439 function DefineOwnProperty(obj, p, desc, should_throw) { | |
| 440 var flag = desc.isEnumerable() ? 0 : DONT_ENUM; | |
| 441 if (IsDataDescriptor(desc)) { | |
| 442 flag |= desc.isWritable() ? 0 : (DONT_DELETE | READ_ONLY); | |
| 443 %SetProperty(obj, p, desc.getValue(), flag); | |
| 444 } else { | |
| 445 if (IS_FUNCTION(desc.getGet())) %DefineAccessor(obj, p, GETTER, desc.getGet( ), flag); | |
| 446 if (IS_FUNCTION(desc.getSet())) %DefineAccessor(obj, p, SETTER, desc.getSet( ), flag); | |
| 447 } | |
| 448 return true; | |
| 449 } | |
| 450 | |
| 451 | |
| 452 // ES5 section 15.2.3.5. | |
| 453 function ObjectCreate(proto, properties) { | |
| 454 if (!IS_OBJECT(proto) && !IS_NULL(proto)) { | |
| 455 throw MakeTypeError("proto_object_or_null", [proto]); | |
| 456 } | |
| 457 var obj = new $Object(); | |
| 458 obj.__proto__ = proto; | |
| 459 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties); | |
| 460 return obj; | |
| 461 } | |
| 462 | |
| 463 | |
| 464 // ES5 section 15.2.3.7. This version cannot cope with the properies already | |
| 465 // being present on obj. Therefore it is not exposed as | |
| 466 // Object.defineProperties yet. | |
| 467 function ObjectDefineProperties(obj, properties) { | |
| 468 var props = ToObject(properties); | |
| 469 var key_values = []; | |
| 470 for (var key in props) { | |
| 471 if (%HasLocalProperty(props, key)) { | |
| 472 key_values.push(key); | |
| 473 var value = props[key]; | |
| 474 var desc = ToPropertyDescriptor(value); | |
| 475 key_values.push(desc); | |
| 476 } | |
| 477 } | |
| 478 for (var i = 0; i < key_values.length; i += 2) { | |
| 479 var key = key_values[i]; | |
| 480 var desc = key_values[i + 1]; | |
| 481 DefineOwnProperty(obj, key, desc, true); | |
| 482 } | |
| 483 } | |
| 484 | |
| 485 | |
| 283 %SetCode($Object, function(x) { | 486 %SetCode($Object, function(x) { |
| 284 if (%_IsConstructCall()) { | 487 if (%_IsConstructCall()) { |
| 285 if (x == null) return this; | 488 if (x == null) return this; |
| 286 return ToObject(x); | 489 return ToObject(x); |
| 287 } else { | 490 } else { |
| 288 if (x == null) return { }; | 491 if (x == null) return { }; |
| 289 return ToObject(x); | 492 return ToObject(x); |
| 290 } | 493 } |
| 291 }); | 494 }); |
| 292 | 495 |
| 293 | 496 |
| 294 // ---------------------------------------------------------------------------- | 497 // ---------------------------------------------------------------------------- |
| 295 | 498 |
| 296 | 499 |
| 297 function SetupObject() { | 500 function SetupObject() { |
| 298 // Setup non-enumerable functions on the Object.prototype object. | 501 // Setup non-enumerable functions on the Object.prototype object. |
| 299 InstallFunctions($Object.prototype, DONT_ENUM, $Array( | 502 InstallFunctions($Object.prototype, DONT_ENUM, $Array( |
| 300 "toString", ObjectToString, | 503 "toString", ObjectToString, |
| 301 "toLocaleString", ObjectToLocaleString, | 504 "toLocaleString", ObjectToLocaleString, |
| 302 "valueOf", ObjectValueOf, | 505 "valueOf", ObjectValueOf, |
| 303 "hasOwnProperty", ObjectHasOwnProperty, | 506 "hasOwnProperty", ObjectHasOwnProperty, |
| 304 "isPrototypeOf", ObjectIsPrototypeOf, | 507 "isPrototypeOf", ObjectIsPrototypeOf, |
| 305 "propertyIsEnumerable", ObjectPropertyIsEnumerable, | 508 "propertyIsEnumerable", ObjectPropertyIsEnumerable, |
| 306 "__defineGetter__", ObjectDefineGetter, | 509 "__defineGetter__", ObjectDefineGetter, |
| 307 "__lookupGetter__", ObjectLookupGetter, | 510 "__lookupGetter__", ObjectLookupGetter, |
| 308 "__defineSetter__", ObjectDefineSetter, | 511 "__defineSetter__", ObjectDefineSetter, |
| 309 "__lookupSetter__", ObjectLookupSetter | 512 "__lookupSetter__", ObjectLookupSetter |
| 310 )); | 513 )); |
| 311 InstallFunctions($Object, DONT_ENUM, $Array( | 514 InstallFunctions($Object, DONT_ENUM, $Array( |
| 312 "keys", ObjectKeys | 515 "keys", ObjectKeys, |
| 516 "create", ObjectCreate | |
| 313 )); | 517 )); |
| 314 } | 518 } |
| 315 | 519 |
| 316 SetupObject(); | 520 SetupObject(); |
| 317 | 521 |
| 318 | 522 |
| 319 // ---------------------------------------------------------------------------- | 523 // ---------------------------------------------------------------------------- |
| 320 // Boolean | 524 // Boolean |
| 321 | 525 |
| 322 function BooleanToString() { | 526 function BooleanToString() { |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 | 774 |
| 571 // ---------------------------------------------------------------------------- | 775 // ---------------------------------------------------------------------------- |
| 572 | 776 |
| 573 function SetupFunction() { | 777 function SetupFunction() { |
| 574 InstallFunctions($Function.prototype, DONT_ENUM, $Array( | 778 InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
| 575 "toString", FunctionToString | 779 "toString", FunctionToString |
| 576 )); | 780 )); |
| 577 } | 781 } |
| 578 | 782 |
| 579 SetupFunction(); | 783 SetupFunction(); |
| OLD | NEW |