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 |