deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / runtime / runtime-classes.cc
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdlib.h>
6 #include <limits>
7
8 #include "src/v8.h"
9
10 #include "src/isolate-inl.h"
11 #include "src/runtime/runtime.h"
12 #include "src/runtime/runtime-utils.h"
13
14
15 namespace v8 {
16 namespace internal {
17
18
19 RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) {
20   HandleScope scope(isolate);
21   DCHECK(args.length() == 0);
22   THROW_NEW_ERROR_RETURN_FAILURE(
23       isolate, NewReferenceError("non_method", HandleVector<Object>(NULL, 0)));
24 }
25
26
27 static Object* ThrowUnsupportedSuper(Isolate* isolate) {
28   THROW_NEW_ERROR_RETURN_FAILURE(
29       isolate,
30       NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
31 }
32
33
34 RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
35   HandleScope scope(isolate);
36   DCHECK(args.length() == 0);
37   return ThrowUnsupportedSuper(isolate);
38 }
39
40
41 RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) {
42   HandleScope scope(isolate);
43   DCHECK(args.length() == 0);
44   THROW_NEW_ERROR_RETURN_FAILURE(
45       isolate,
46       NewTypeError("constructor_noncallable", HandleVector<Object>(NULL, 0)));
47 }
48
49
50 RUNTIME_FUNCTION(Runtime_ThrowArrayNotSubclassableError) {
51   HandleScope scope(isolate);
52   DCHECK(args.length() == 0);
53   THROW_NEW_ERROR_RETURN_FAILURE(
54       isolate,
55       NewTypeError("array_not_subclassable", HandleVector<Object>(NULL, 0)));
56 }
57
58
59 static Object* ThrowStaticPrototypeError(Isolate* isolate) {
60   THROW_NEW_ERROR_RETURN_FAILURE(
61       isolate, NewTypeError("static_prototype", HandleVector<Object>(NULL, 0)));
62 }
63
64
65 RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
66   HandleScope scope(isolate);
67   DCHECK(args.length() == 0);
68   return ThrowStaticPrototypeError(isolate);
69 }
70
71
72 RUNTIME_FUNCTION(Runtime_ThrowIfStaticPrototype) {
73   HandleScope scope(isolate);
74   DCHECK(args.length() == 1);
75   CONVERT_ARG_HANDLE_CHECKED(Name, name, 0);
76   if (Name::Equals(name, isolate->factory()->prototype_string())) {
77     return ThrowStaticPrototypeError(isolate);
78   }
79   return *name;
80 }
81
82
83 RUNTIME_FUNCTION(Runtime_ToMethod) {
84   HandleScope scope(isolate);
85   DCHECK(args.length() == 2);
86   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
87   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
88   Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
89   Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
90   JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
91                                            home_object, DONT_ENUM).Assert();
92   return *clone;
93 }
94
95
96 RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
97   DCHECK(args.length() == 0);
98   return isolate->heap()->home_object_symbol();
99 }
100
101
102 RUNTIME_FUNCTION(Runtime_DefineClass) {
103   HandleScope scope(isolate);
104   DCHECK(args.length() == 6);
105   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
106   CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1);
107   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2);
108   CONVERT_ARG_HANDLE_CHECKED(Script, script, 3);
109   CONVERT_SMI_ARG_CHECKED(start_position, 4);
110   CONVERT_SMI_ARG_CHECKED(end_position, 5);
111
112   Handle<Object> prototype_parent;
113   Handle<Object> constructor_parent;
114
115   if (super_class->IsTheHole()) {
116     prototype_parent = isolate->initial_object_prototype();
117   } else {
118     if (super_class->IsNull()) {
119       prototype_parent = isolate->factory()->null_value();
120     } else if (super_class->IsSpecFunction()) {
121       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
122           isolate, prototype_parent,
123           Runtime::GetObjectProperty(isolate, super_class,
124                                      isolate->factory()->prototype_string()));
125       if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) {
126         Handle<Object> args[1] = {prototype_parent};
127         THROW_NEW_ERROR_RETURN_FAILURE(
128             isolate, NewTypeError("prototype_parent_not_an_object",
129                                   HandleVector(args, 1)));
130       }
131       constructor_parent = super_class;
132     } else {
133       // TODO(arv): Should be IsConstructor.
134       Handle<Object> args[1] = {super_class};
135       THROW_NEW_ERROR_RETURN_FAILURE(
136           isolate,
137           NewTypeError("extends_value_not_a_function", HandleVector(args, 1)));
138     }
139   }
140
141   Handle<Map> map =
142       isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
143   map->SetPrototype(prototype_parent);
144   map->SetConstructor(*constructor);
145   Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map);
146
147   Handle<String> name_string = name->IsString()
148                                    ? Handle<String>::cast(name)
149                                    : isolate->factory()->empty_string();
150   constructor->shared()->set_name(*name_string);
151
152   if (!super_class->IsTheHole()) {
153     Handle<Code> stub(isolate->builtins()->JSConstructStubForDerived());
154     constructor->shared()->set_construct_stub(*stub);
155   }
156
157   JSFunction::SetPrototype(constructor, prototype);
158   PropertyAttributes attribs =
159       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
160   RETURN_FAILURE_ON_EXCEPTION(
161       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
162                    constructor, isolate->factory()->prototype_string(),
163                    prototype, attribs));
164
165   // TODO(arv): Only do this conditionally.
166   Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
167   RETURN_FAILURE_ON_EXCEPTION(
168       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
169                    constructor, home_object_symbol, prototype, DONT_ENUM));
170
171   if (!constructor_parent.is_null()) {
172     RETURN_FAILURE_ON_EXCEPTION(
173         isolate,
174         JSObject::SetPrototype(constructor, constructor_parent, false));
175   }
176
177   JSObject::AddProperty(prototype, isolate->factory()->constructor_string(),
178                         constructor, DONT_ENUM);
179
180   // Install private properties that are used to construct the FunctionToString.
181   RETURN_FAILURE_ON_EXCEPTION(
182       isolate, Object::SetProperty(constructor,
183                                    isolate->factory()->class_script_symbol(),
184                                    script, STRICT));
185   RETURN_FAILURE_ON_EXCEPTION(
186       isolate,
187       Object::SetProperty(
188           constructor, isolate->factory()->class_start_position_symbol(),
189           handle(Smi::FromInt(start_position), isolate), STRICT));
190   RETURN_FAILURE_ON_EXCEPTION(
191       isolate, Object::SetProperty(
192                    constructor, isolate->factory()->class_end_position_symbol(),
193                    handle(Smi::FromInt(end_position), isolate), STRICT));
194
195   return *constructor;
196 }
197
198
199 RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
200   HandleScope scope(isolate);
201   DCHECK(args.length() == 3);
202   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
203   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
204   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
205
206   uint32_t index;
207   if (name->AsArrayIndex(&index)) {
208     RETURN_FAILURE_ON_EXCEPTION(
209         isolate,
210         JSObject::SetOwnElement(object, index, function, DONT_ENUM, STRICT));
211   } else {
212     RETURN_FAILURE_ON_EXCEPTION(
213         isolate, JSObject::SetOwnPropertyIgnoreAttributes(object, name,
214                                                           function, DONT_ENUM));
215   }
216   return isolate->heap()->undefined_value();
217 }
218
219
220 RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
221   HandleScope shs(isolate);
222   DCHECK(args.length() == 1);
223   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
224
225   Handle<Object> script;
226   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
227       isolate, script,
228       Object::GetProperty(fun, isolate->factory()->class_script_symbol()));
229   if (!script->IsScript()) {
230     return isolate->heap()->undefined_value();
231   }
232
233   Handle<Symbol> start_position_symbol(
234       isolate->heap()->class_start_position_symbol());
235   Handle<Object> start_position;
236   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
237       isolate, start_position, Object::GetProperty(fun, start_position_symbol));
238
239   Handle<Symbol> end_position_symbol(
240       isolate->heap()->class_end_position_symbol());
241   Handle<Object> end_position;
242   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
243       isolate, end_position, Object::GetProperty(fun, end_position_symbol));
244
245   if (!start_position->IsSmi() || !end_position->IsSmi() ||
246       !Handle<Script>::cast(script)->HasValidSource()) {
247     return isolate->ThrowIllegalOperation();
248   }
249
250   Handle<String> source(String::cast(Handle<Script>::cast(script)->source()));
251   return *isolate->factory()->NewSubString(
252       source, Handle<Smi>::cast(start_position)->value(),
253       Handle<Smi>::cast(end_position)->value());
254 }
255
256
257 static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
258                              Handle<JSObject> home_object, Handle<Name> name) {
259   if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
260     isolate->ReportFailedAccessCheck(home_object);
261     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
262   }
263
264   PrototypeIterator iter(isolate, home_object);
265   Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
266   if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
267
268   LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
269   Handle<Object> result;
270   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
271   return *result;
272 }
273
274
275 static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
276                                     Handle<JSObject> home_object,
277                                     uint32_t index) {
278   if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
279     isolate->ReportFailedAccessCheck(home_object);
280     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
281   }
282
283   PrototypeIterator iter(isolate, home_object);
284   Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
285   if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
286
287   Handle<Object> result;
288   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
289       isolate, result,
290       Object::GetElementWithReceiver(isolate, proto, receiver, index));
291   return *result;
292 }
293
294
295 RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
296   HandleScope scope(isolate);
297   DCHECK(args.length() == 3);
298   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
299   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
300   CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
301
302   return LoadFromSuper(isolate, receiver, home_object, name);
303 }
304
305
306 RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
307   HandleScope scope(isolate);
308   DCHECK(args.length() == 3);
309   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
310   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
311   CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
312
313   uint32_t index;
314   if (key->ToArrayIndex(&index)) {
315     return LoadElementFromSuper(isolate, receiver, home_object, index);
316   }
317
318   Handle<Name> name;
319   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
320                                      Runtime::ToName(isolate, key));
321   if (name->AsArrayIndex(&index)) {
322     return LoadElementFromSuper(isolate, receiver, home_object, index);
323   }
324   return LoadFromSuper(isolate, receiver, home_object, name);
325 }
326
327
328 static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
329                             Handle<Object> receiver, Handle<Name> name,
330                             Handle<Object> value, LanguageMode language_mode) {
331   if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
332     isolate->ReportFailedAccessCheck(home_object);
333     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
334   }
335
336   PrototypeIterator iter(isolate, home_object);
337   Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
338   if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
339
340   LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
341   Handle<Object> result;
342   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
343       isolate, result,
344       Object::SetSuperProperty(&it, value, language_mode,
345                                Object::CERTAINLY_NOT_STORE_FROM_KEYED));
346   return *result;
347 }
348
349
350 static Object* StoreElementToSuper(Isolate* isolate,
351                                    Handle<JSObject> home_object,
352                                    Handle<Object> receiver, uint32_t index,
353                                    Handle<Object> value,
354                                    LanguageMode language_mode) {
355   if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
356     isolate->ReportFailedAccessCheck(home_object);
357     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
358   }
359
360   PrototypeIterator iter(isolate, home_object);
361   Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
362   if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
363
364   Handle<Object> result;
365   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
366       isolate, result,
367       Object::SetElementWithReceiver(isolate, proto, receiver, index, value,
368                                      language_mode));
369   return *result;
370 }
371
372
373 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
374   HandleScope scope(isolate);
375   DCHECK(args.length() == 4);
376   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
377   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
378   CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
379   CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
380
381   return StoreToSuper(isolate, home_object, receiver, name, value, STRICT);
382 }
383
384
385 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
386   HandleScope scope(isolate);
387   DCHECK(args.length() == 4);
388   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
389   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
390   CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
391   CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
392
393   return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY);
394 }
395
396
397 static Object* StoreKeyedToSuper(Isolate* isolate, Handle<JSObject> home_object,
398                                  Handle<Object> receiver, Handle<Object> key,
399                                  Handle<Object> value,
400                                  LanguageMode language_mode) {
401   uint32_t index;
402
403   if (key->ToArrayIndex(&index)) {
404     return StoreElementToSuper(isolate, home_object, receiver, index, value,
405                                language_mode);
406   }
407   Handle<Name> name;
408   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
409                                      Runtime::ToName(isolate, key));
410   if (name->AsArrayIndex(&index)) {
411     return StoreElementToSuper(isolate, home_object, receiver, index, value,
412                                language_mode);
413   }
414   return StoreToSuper(isolate, home_object, receiver, name, value,
415                       language_mode);
416 }
417
418
419 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) {
420   HandleScope scope(isolate);
421   DCHECK(args.length() == 4);
422   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
423   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
424   CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
425   CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
426
427   return StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT);
428 }
429
430
431 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
432   HandleScope scope(isolate);
433   DCHECK(args.length() == 4);
434   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
435   CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
436   CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
437   CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
438
439   return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY);
440 }
441
442
443 RUNTIME_FUNCTION(Runtime_HandleStepInForDerivedConstructors) {
444   HandleScope scope(isolate);
445   DCHECK(args.length() == 1);
446   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
447   Debug* debug = isolate->debug();
448   // Handle stepping into constructors if step into is active.
449   if (debug->StepInActive()) {
450     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
451   }
452   return *isolate->factory()->undefined_value();
453 }
454
455
456 RUNTIME_FUNCTION(Runtime_DefaultConstructorCallSuper) {
457   UNIMPLEMENTED();
458   return nullptr;
459 }
460 }
461 }  // namespace v8::internal