Skip to content

Commit 61ab205

Browse files
kkristofgalpeter
authored andcommitted
Implement Object.create function
JerryScript-DCO-1.0-Signed-off-by: Kristof Kosztyo kkosztyo.u-szeged@partner.samsung.com
1 parent 3f28cb3 commit 61ab205

File tree

4 files changed

+215
-11
lines changed

4 files changed

+215
-11
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-object.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,46 @@ ecma_builtin_object_object_create (ecma_value_t this_arg, /**< 'this' argument *
637637
ecma_value_t arg1, /**< routine's first argument */
638638
ecma_value_t arg2) /**< routine's second argument */
639639
{
640-
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, arg1, arg2);
640+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
641+
642+
// 1.
643+
if (!ecma_is_value_object (arg1) && !ecma_is_value_null (arg1))
644+
{
645+
ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
646+
}
647+
else
648+
{
649+
ecma_object_t *obj_p = NULL;
650+
651+
if (!ecma_is_value_null (arg1))
652+
{
653+
obj_p = ecma_get_object_from_value (arg1);
654+
}
655+
// 2-3.
656+
ecma_object_t *result_obj_p = ecma_op_create_object_object_noarg_and_set_prototype (obj_p);
657+
658+
// 4.
659+
if (!ecma_is_value_undefined (arg2))
660+
{
661+
ECMA_TRY_CATCH (obj,
662+
ecma_builtin_object_object_define_properties (this_arg,
663+
ecma_make_object_value (result_obj_p),
664+
arg2),
665+
ret_value);
666+
ECMA_FINALIZE (obj);
667+
}
668+
669+
// 5.
670+
if (ecma_is_completion_value_empty (ret_value))
671+
{
672+
ret_value = ecma_make_normal_completion_value (ecma_copy_value (ecma_make_object_value (result_obj_p),
673+
true));
674+
}
675+
676+
ecma_deref_object (result_obj_p);
677+
}
678+
679+
return ret_value;
641680
} /* ecma_builtin_object_object_create */
642681

643682
/**

jerry-core/ecma/operations/ecma-objects-general.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,10 @@ ecma_op_create_object_object_noarg (void)
6262
ecma_object_t *object_prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
6363

6464
// 3., 4., 6., 7.
65-
ecma_object_t *obj_p = ecma_create_object (object_prototype_p, true, ECMA_OBJECT_TYPE_GENERAL);
65+
ecma_object_t *obj_p = ecma_op_create_object_object_noarg_and_set_prototype (object_prototype_p);
6666

6767
ecma_deref_object (object_prototype_p);
6868

69-
/*
70-
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
71-
* without ECMA_INTERNAL_PROPERTY_CLASS internal property
72-
* is "Object".
73-
*
74-
* See also: ecma_object_get_class_name
75-
*/
76-
7769
return obj_p;
7870
} /* ecma_op_create_object_object_noarg */
7971

@@ -109,6 +101,32 @@ ecma_op_create_object_object_arg (ecma_value_t value) /**< argument of construct
109101
}
110102
} /* ecma_op_create_object_object_arg */
111103

104+
/**
105+
* Object creation operation with no arguments.
106+
* It sets the given prototype to the newly created object.
107+
*
108+
* See also: ECMA-262 v5, 15.2.2.1, 15.2.3.5
109+
*
110+
* @return pointer to newly created object
111+
*/
112+
ecma_object_t*
113+
ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prototype_p) /**< pointer to prototype of
114+
the object
115+
(can be NULL) */
116+
{
117+
ecma_object_t *obj_p = ecma_create_object (object_prototype_p, true, ECMA_OBJECT_TYPE_GENERAL);
118+
119+
/*
120+
* [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
121+
* without ECMA_INTERNAL_PROPERTY_CLASS internal property
122+
* is "Object".
123+
*
124+
* See also: ecma_object_get_class_name
125+
*/
126+
127+
return obj_p;
128+
} /* ecma_op_create_object_object_noarg_and_set_prototype */
129+
112130
/**
113131
* [[Get]] ecma general object's operation
114132
*

jerry-core/ecma/operations/ecma-objects-general.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
* @{
2727
*/
2828

29-
extern ecma_object_t* ecma_op_create_object_object_noarg (void);
29+
extern ecma_object_t *ecma_op_create_object_object_noarg (void);
3030
extern ecma_completion_value_t ecma_op_create_object_object_arg (ecma_value_t value);
31+
extern ecma_object_t *ecma_op_create_object_object_noarg_and_set_prototype (ecma_object_t *object_prototype_p);
3132

3233
extern ecma_completion_value_t ecma_op_general_object_get (ecma_object_t *obj_p,
3334
ecma_string_t *property_name_p);

tests/jerry/object-create.js

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// Copyright 2015 Samsung Electronics Co., Ltd.
2+
// Copyright 2015 University of Szeged.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
// Example where we create an object with a couple of sample properties.
17+
// (Note that the second parameter maps keys to *property descriptors*.)
18+
var o = Object.create(Object.prototype, {
19+
// foo is a regular 'value property'
20+
foo: { writable: true, configurable: true, value: 'hello' },
21+
// bar is a getter-and-setter (accessor) property
22+
bar: {
23+
configurable: false,
24+
get: function() { return 10; },
25+
set: function(value) { console.log('Setting `o.bar` to', value); }
26+
}
27+
});
28+
29+
// create a new object whose prototype is a new, empty object
30+
// and a adding single property 'p', with value 42
31+
var o = Object.create({}, { p: { value: 42 } });
32+
// by default properties ARE NOT writable, enumerable or configurable:
33+
o.p = 24;
34+
assert (o.p === 42);
35+
36+
// to specify an ES3 property
37+
var o2 = Object.create({}, {
38+
p: {
39+
value: 42,
40+
writable: true,
41+
enumerable: true,
42+
configurable: true
43+
}
44+
});
45+
46+
assert (o2.p === 42);
47+
48+
// Shape - superclass
49+
function Shape() {
50+
this.x = 0;
51+
this.y = 0;
52+
}
53+
54+
// superclass method
55+
Shape.prototype.move = function(x, y) {
56+
this.x += x;
57+
this.y += y;
58+
};
59+
60+
// Rectangle - subclass
61+
function Rectangle() {
62+
Shape.call(this); // call super constructor.
63+
}
64+
65+
// subclass extends superclass
66+
Rectangle.prototype = Object.create(Shape.prototype);
67+
Rectangle.prototype.constructor = Rectangle;
68+
69+
var rect = new Rectangle();
70+
71+
assert (rect instanceof Rectangle);
72+
assert (rect instanceof Shape);
73+
rect.move(1, 1);
74+
assert (rect.x === 1)
75+
assert (rect.y === 1);
76+
77+
var obj = {
78+
protoFunction: function() {
79+
return 3;
80+
}
81+
};
82+
83+
Object.defineProperties(obj, {
84+
"foo": {
85+
value: 42,
86+
writable: true,
87+
},
88+
"a": {
89+
value: "b",
90+
configurable: true
91+
},
92+
"bar": {
93+
get: function() {
94+
return this.foo;
95+
},
96+
},
97+
});
98+
99+
var obj2 = Object.create(obj);
100+
101+
assert (obj2.protoFunction() === 3);
102+
assert (obj2.foo === 42);
103+
assert (obj2.a === "b");
104+
assert (obj2.bar === 42);
105+
assert (Object.getPrototypeOf (obj2) === obj);
106+
107+
108+
var props = {
109+
prop1: {
110+
value: 1,
111+
},
112+
hey: function () {
113+
return "ho";
114+
}
115+
};
116+
117+
var obj3 = Object.create(obj, props);
118+
assert (obj3.prop1 === 1);
119+
assert (obj3.protoFunction());
120+
try {
121+
assert (obj3.hey === undefined);
122+
obj3.hey();
123+
assert (false);
124+
} catch (e) {
125+
assert (e instanceof TypeError);
126+
}
127+
128+
// Create an object with null as prototype
129+
var obj = Object.create(null)
130+
assert (typeof (obj) === "object");
131+
// FIXME: enable this assertion after the #208 is fixed.
132+
// assert (Object.getPrototypeOf (obj) === null);
133+
134+
try {
135+
Object.create()
136+
assert (false);
137+
} catch (e) {
138+
assert (e instanceof TypeError);
139+
}
140+
141+
try {
142+
Object.create(undefined)
143+
assert (false);
144+
} catch (e) {
145+
assert (e instanceof TypeError);
146+
}

0 commit comments

Comments
 (0)