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 RUNTIME_FUNCTION(Runtime_ToMethod) {
60 HandleScope scope(isolate);
61 DCHECK(args.length() == 2);
62 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
63 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
64 Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
65 Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
66 JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
67 home_object, DONT_ENUM).Assert();
72 RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
73 DCHECK(args.length() == 0);
74 return isolate->heap()->home_object_symbol();
78 RUNTIME_FUNCTION(Runtime_DefineClass) {
79 HandleScope scope(isolate);
80 DCHECK(args.length() == 6);
81 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
82 CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1);
83 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2);
84 CONVERT_ARG_HANDLE_CHECKED(Script, script, 3);
85 CONVERT_SMI_ARG_CHECKED(start_position, 4);
86 CONVERT_SMI_ARG_CHECKED(end_position, 5);
88 Handle<Object> prototype_parent;
89 Handle<Object> constructor_parent;
91 if (super_class->IsTheHole()) {
92 prototype_parent = isolate->initial_object_prototype();
94 if (super_class->IsNull()) {
95 prototype_parent = isolate->factory()->null_value();
96 } else if (super_class->IsSpecFunction()) {
97 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
98 isolate, prototype_parent,
99 Runtime::GetObjectProperty(isolate, super_class,
100 isolate->factory()->prototype_string()));
101 if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) {
102 Handle<Object> args[1] = {prototype_parent};
103 THROW_NEW_ERROR_RETURN_FAILURE(
104 isolate, NewTypeError("prototype_parent_not_an_object",
105 HandleVector(args, 1)));
107 constructor_parent = super_class;
109 // TODO(arv): Should be IsConstructor.
110 Handle<Object> args[1] = {super_class};
111 THROW_NEW_ERROR_RETURN_FAILURE(
113 NewTypeError("extends_value_not_a_function", HandleVector(args, 1)));
118 isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
119 map->SetPrototype(prototype_parent);
120 map->set_constructor(*constructor);
121 Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map);
123 Handle<String> name_string = name->IsString()
124 ? Handle<String>::cast(name)
125 : isolate->factory()->empty_string();
126 constructor->shared()->set_name(*name_string);
128 if (!super_class->IsTheHole()) {
129 Handle<Code> stub(isolate->builtins()->JSConstructStubForDerived());
130 constructor->shared()->set_construct_stub(*stub);
133 JSFunction::SetPrototype(constructor, prototype);
134 PropertyAttributes attribs =
135 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
136 RETURN_FAILURE_ON_EXCEPTION(
137 isolate, JSObject::SetOwnPropertyIgnoreAttributes(
138 constructor, isolate->factory()->prototype_string(),
139 prototype, attribs));
141 // TODO(arv): Only do this conditionally.
142 Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
143 RETURN_FAILURE_ON_EXCEPTION(
144 isolate, JSObject::SetOwnPropertyIgnoreAttributes(
145 constructor, home_object_symbol, prototype, DONT_ENUM));
147 if (!constructor_parent.is_null()) {
148 RETURN_FAILURE_ON_EXCEPTION(
150 JSObject::SetPrototype(constructor, constructor_parent, false));
153 JSObject::AddProperty(prototype, isolate->factory()->constructor_string(),
154 constructor, DONT_ENUM);
156 // Install private properties that are used to construct the FunctionToString.
157 RETURN_FAILURE_ON_EXCEPTION(
158 isolate, Object::SetProperty(constructor,
159 isolate->factory()->class_script_symbol(),
161 RETURN_FAILURE_ON_EXCEPTION(
164 constructor, isolate->factory()->class_start_position_symbol(),
165 handle(Smi::FromInt(start_position), isolate), STRICT));
166 RETURN_FAILURE_ON_EXCEPTION(
167 isolate, Object::SetProperty(
168 constructor, isolate->factory()->class_end_position_symbol(),
169 handle(Smi::FromInt(end_position), isolate), STRICT));
175 RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
176 HandleScope scope(isolate);
177 DCHECK(args.length() == 3);
178 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
179 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
180 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
183 if (name->AsArrayIndex(&index)) {
184 RETURN_FAILURE_ON_EXCEPTION(
186 JSObject::SetOwnElement(object, index, function, DONT_ENUM, STRICT));
188 RETURN_FAILURE_ON_EXCEPTION(
189 isolate, JSObject::SetOwnPropertyIgnoreAttributes(object, name,
190 function, DONT_ENUM));
192 return isolate->heap()->undefined_value();
196 RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
197 HandleScope shs(isolate);
198 DCHECK(args.length() == 1);
199 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
201 Handle<Object> script;
202 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
204 Object::GetProperty(fun, isolate->factory()->class_script_symbol()));
205 if (!script->IsScript()) {
206 return isolate->heap()->undefined_value();
209 Handle<Symbol> start_position_symbol(
210 isolate->heap()->class_start_position_symbol());
211 Handle<Object> start_position;
212 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
213 isolate, start_position, Object::GetProperty(fun, start_position_symbol));
215 Handle<Symbol> end_position_symbol(
216 isolate->heap()->class_end_position_symbol());
217 Handle<Object> end_position;
218 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
219 isolate, end_position, Object::GetProperty(fun, end_position_symbol));
221 if (!start_position->IsSmi() || !end_position->IsSmi() ||
222 !Handle<Script>::cast(script)->HasValidSource()) {
223 return isolate->ThrowIllegalOperation();
226 Handle<String> source(String::cast(Handle<Script>::cast(script)->source()));
227 return *isolate->factory()->NewSubString(
228 source, Handle<Smi>::cast(start_position)->value(),
229 Handle<Smi>::cast(end_position)->value());
233 static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
234 Handle<JSObject> home_object, Handle<Name> name) {
235 if (home_object->IsAccessCheckNeeded() &&
236 !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
237 isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
238 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
241 PrototypeIterator iter(isolate, home_object);
242 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
243 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
245 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
246 Handle<Object> result;
247 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
252 static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
253 Handle<JSObject> home_object,
255 if (home_object->IsAccessCheckNeeded() &&
256 !isolate->MayIndexedAccess(home_object, index, v8::ACCESS_GET)) {
257 isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
258 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
261 PrototypeIterator iter(isolate, home_object);
262 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
263 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
265 Handle<Object> result;
266 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
268 Object::GetElementWithReceiver(isolate, proto, receiver, index));
273 RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
274 HandleScope scope(isolate);
275 DCHECK(args.length() == 3);
276 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
277 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
278 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
280 return LoadFromSuper(isolate, receiver, home_object, name);
284 RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
285 HandleScope scope(isolate);
286 DCHECK(args.length() == 3);
287 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
288 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
289 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
292 if (key->ToArrayIndex(&index)) {
293 return LoadElementFromSuper(isolate, receiver, home_object, index);
297 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
298 Runtime::ToName(isolate, key));
299 if (name->AsArrayIndex(&index)) {
300 return LoadElementFromSuper(isolate, receiver, home_object, index);
302 return LoadFromSuper(isolate, receiver, home_object, name);
306 static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
307 Handle<Object> receiver, Handle<Name> name,
308 Handle<Object> value, LanguageMode language_mode) {
309 if (home_object->IsAccessCheckNeeded() &&
310 !isolate->MayNamedAccess(home_object, name, v8::ACCESS_SET)) {
311 isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
312 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
315 PrototypeIterator iter(isolate, home_object);
316 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
317 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
319 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
320 Handle<Object> result;
321 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
323 Object::SetSuperProperty(&it, value, language_mode,
324 Object::CERTAINLY_NOT_STORE_FROM_KEYED));
329 static Object* StoreElementToSuper(Isolate* isolate,
330 Handle<JSObject> home_object,
331 Handle<Object> receiver, uint32_t index,
332 Handle<Object> value,
333 LanguageMode language_mode) {
334 if (home_object->IsAccessCheckNeeded() &&
335 !isolate->MayIndexedAccess(home_object, index, v8::ACCESS_SET)) {
336 isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
337 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
340 PrototypeIterator iter(isolate, home_object);
341 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
342 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
344 Handle<Object> result;
345 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
347 Object::SetElementWithReceiver(isolate, proto, receiver, index, value,
353 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
354 HandleScope scope(isolate);
355 DCHECK(args.length() == 4);
356 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
357 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
358 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
359 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
361 return StoreToSuper(isolate, home_object, receiver, name, value, STRICT);
365 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
366 HandleScope scope(isolate);
367 DCHECK(args.length() == 4);
368 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
369 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
370 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
371 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
373 return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY);
377 static Object* StoreKeyedToSuper(Isolate* isolate, Handle<JSObject> home_object,
378 Handle<Object> receiver, Handle<Object> key,
379 Handle<Object> value,
380 LanguageMode language_mode) {
383 if (key->ToArrayIndex(&index)) {
384 return StoreElementToSuper(isolate, home_object, receiver, index, value,
388 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
389 Runtime::ToName(isolate, key));
390 if (name->AsArrayIndex(&index)) {
391 return StoreElementToSuper(isolate, home_object, receiver, index, value,
394 return StoreToSuper(isolate, home_object, receiver, name, value,
399 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) {
400 HandleScope scope(isolate);
401 DCHECK(args.length() == 4);
402 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
403 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
404 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
405 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
407 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT);
411 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
412 HandleScope scope(isolate);
413 DCHECK(args.length() == 4);
414 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
415 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
416 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
417 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
419 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY);
423 RUNTIME_FUNCTION(Runtime_HandleStepInForDerivedConstructors) {
424 HandleScope scope(isolate);
425 DCHECK(args.length() == 1);
426 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
427 Debug* debug = isolate->debug();
428 // Handle stepping into constructors if step into is active.
429 if (debug->StepInActive()) {
430 debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
432 return *isolate->factory()->undefined_value();
436 RUNTIME_FUNCTION(RuntimeReference_DefaultConstructorCallSuper) {
441 } // namespace v8::internal