Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(785)

Side by Side Diff: src/v8natives.js

Issue 463040: Add Object.create from ECMAScript5. Supports value, writable, enumerable, ge... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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();
OLDNEW
« no previous file with comments | « src/messages.js ('k') | test/mjsunit/object-create.js » ('j') | test/mjsunit/object-create.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698