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.
10 #include "src/isolate-inl.h"
11 #include "src/runtime/runtime.h"
12 #include "src/runtime/runtime-utils.h"
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)));
27 static Object* ThrowUnsupportedSuper(Isolate* isolate) {
28 THROW_NEW_ERROR_RETURN_FAILURE(
30 NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
34 RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
35 HandleScope scope(isolate);
36 DCHECK(args.length() == 0);
37 return ThrowUnsupportedSuper(isolate);
41 RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) {
42 HandleScope scope(isolate);
43 DCHECK(args.length() == 0);
44 THROW_NEW_ERROR_RETURN_FAILURE(
46 NewTypeError("constructor_noncallable", HandleVector<Object>(NULL, 0)));
50 RUNTIME_FUNCTION(Runtime_ThrowArrayNotSubclassableError) {
51 HandleScope scope(isolate);
52 DCHECK(args.length() == 0);
53 THROW_NEW_ERROR_RETURN_FAILURE(
55 NewTypeError("array_not_subclassable", HandleVector<Object>(NULL, 0)));
59 static Object* ThrowStaticPrototypeError(Isolate* isolate) {
60 THROW_NEW_ERROR_RETURN_FAILURE(
61 isolate, NewTypeError("static_prototype", HandleVector<Object>(NULL, 0)));
65 RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
66 HandleScope scope(isolate);
67 DCHECK(args.length() == 0);
68 return ThrowStaticPrototypeError(isolate);
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);
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();
96 RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
97 DCHECK(args.length() == 0);
98 return isolate->heap()->home_object_symbol();
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);
112 Handle<Object> prototype_parent;
113 Handle<Object> constructor_parent;
115 if (super_class->IsTheHole()) {
116 prototype_parent = isolate->initial_object_prototype();
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)));
131 constructor_parent = super_class;
133 // TODO(arv): Should be IsConstructor.
134 Handle<Object> args[1] = {super_class};
135 THROW_NEW_ERROR_RETURN_FAILURE(
137 NewTypeError("extends_value_not_a_function", HandleVector(args, 1)));
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);
147 Handle<String> name_string = name->IsString()
148 ? Handle<String>::cast(name)
149 : isolate->factory()->empty_string();
150 constructor->shared()->set_name(*name_string);
152 if (!super_class->IsTheHole()) {
153 Handle<Code> stub(isolate->builtins()->JSConstructStubForDerived());
154 constructor->shared()->set_construct_stub(*stub);
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));
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));
171 if (!constructor_parent.is_null()) {
172 RETURN_FAILURE_ON_EXCEPTION(
174 JSObject::SetPrototype(constructor, constructor_parent, false));
177 JSObject::AddProperty(prototype, isolate->factory()->constructor_string(),
178 constructor, DONT_ENUM);
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(),
185 RETURN_FAILURE_ON_EXCEPTION(
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));
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);
207 if (name->AsArrayIndex(&index)) {
208 RETURN_FAILURE_ON_EXCEPTION(
210 JSObject::SetOwnElement(object, index, function, DONT_ENUM, STRICT));
212 RETURN_FAILURE_ON_EXCEPTION(
213 isolate, JSObject::SetOwnPropertyIgnoreAttributes(object, name,
214 function, DONT_ENUM));
216 return isolate->heap()->undefined_value();
220 RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
221 HandleScope shs(isolate);
222 DCHECK(args.length() == 1);
223 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
225 Handle<Object> script;
226 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
228 Object::GetProperty(fun, isolate->factory()->class_script_symbol()));
229 if (!script->IsScript()) {
230 return isolate->heap()->undefined_value();
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));
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));
245 if (!start_position->IsSmi() || !end_position->IsSmi() ||
246 !Handle<Script>::cast(script)->HasValidSource()) {
247 return isolate->ThrowIllegalOperation();
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());
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);
264 PrototypeIterator iter(isolate, home_object);
265 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
266 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
268 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
269 Handle<Object> result;
270 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
275 static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
276 Handle<JSObject> home_object,
278 if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) {
279 isolate->ReportFailedAccessCheck(home_object);
280 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
283 PrototypeIterator iter(isolate, home_object);
284 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
285 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
287 Handle<Object> result;
288 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
290 Object::GetElementWithReceiver(isolate, proto, receiver, index));
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);
302 return LoadFromSuper(isolate, receiver, home_object, name);
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);
314 if (key->ToArrayIndex(&index)) {
315 return LoadElementFromSuper(isolate, receiver, home_object, index);
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);
324 return LoadFromSuper(isolate, receiver, home_object, name);
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);
336 PrototypeIterator iter(isolate, home_object);
337 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
338 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
340 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
341 Handle<Object> result;
342 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
344 Object::SetSuperProperty(&it, value, language_mode,
345 Object::CERTAINLY_NOT_STORE_FROM_KEYED));
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);
360 PrototypeIterator iter(isolate, home_object);
361 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
362 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
364 Handle<Object> result;
365 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
367 Object::SetElementWithReceiver(isolate, proto, receiver, index, value,
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);
381 return StoreToSuper(isolate, home_object, receiver, name, value, STRICT);
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);
393 return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY);
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) {
403 if (key->ToArrayIndex(&index)) {
404 return StoreElementToSuper(isolate, home_object, receiver, index, value,
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,
414 return StoreToSuper(isolate, home_object, receiver, name, value,
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);
427 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT);
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);
439 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY);
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);
452 return *isolate->factory()->undefined_value();
456 RUNTIME_FUNCTION(Runtime_DefaultConstructorCallSuper) {
461 } // namespace v8::internal