1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
17 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
26
27 #include "third_party/blink/renderer/platform/bindings/origin_trial_features.h"
28 #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
29 #include "third_party/blink/renderer/platform/bindings/v8_binding.h"
30 #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h"
31 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
32 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
33
34 namespace blink {
35
NewInstance(v8::Isolate * isolate,v8::Local<v8::Function> function,int argc,v8::Local<v8::Value> argv[])36 v8::MaybeLocal<v8::Object> V8ObjectConstructor::NewInstance(
37 v8::Isolate* isolate,
38 v8::Local<v8::Function> function,
39 int argc,
40 v8::Local<v8::Value> argv[]) {
41 DCHECK(!function.IsEmpty());
42 TRACE_EVENT0("v8", "v8.newInstance");
43 RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kV8);
44 ConstructorMode constructor_mode(isolate);
45 v8::MicrotasksScope microtasks_scope(
46 isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
47 // Construct without side effect only in ConstructorMode::kWrapExistingObject
48 // cases. This allows whitelisted methods to correctly set return values
49 // without invoking Blink's internal constructors.
50 v8::MaybeLocal<v8::Object> result = function->NewInstanceWithSideEffectType(
51 isolate->GetCurrentContext(), argc, argv,
52 v8::SideEffectType::kHasNoSideEffect);
53 CHECK(!isolate->IsDead());
54 return result;
55 }
56
IsValidConstructorMode(const v8::FunctionCallbackInfo<v8::Value> & info)57 void V8ObjectConstructor::IsValidConstructorMode(
58 const v8::FunctionCallbackInfo<v8::Value>& info) {
59 RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT(info.GetIsolate(),
60 "Blink_IsValidConstructorMode");
61 if (ConstructorMode::Current(info.GetIsolate()) ==
62 ConstructorMode::kCreateNewObject) {
63 V8ThrowException::ThrowTypeError(info.GetIsolate(), "Illegal constructor");
64 return;
65 }
66 V8SetReturnValue(info, info.Holder());
67 }
68
CreateInterfaceObject(const WrapperTypeInfo * type,v8::Local<v8::Context> context,const DOMWrapperWorld & world,v8::Isolate * isolate,v8::Local<v8::Function> parent_interface,CreationMode creation_mode)69 v8::Local<v8::Function> V8ObjectConstructor::CreateInterfaceObject(
70 const WrapperTypeInfo* type,
71 v8::Local<v8::Context> context,
72 const DOMWrapperWorld& world,
73 v8::Isolate* isolate,
74 v8::Local<v8::Function> parent_interface,
75 CreationMode creation_mode) {
76 // We shouldn't reach this point for the types that are implemented in v8 such
77 // as typed arrays and hence don't have DomTemplateFunction.
78 DCHECK(type->dom_template_function);
79 v8::Local<v8::FunctionTemplate> interface_template =
80 type->DomTemplate(isolate, world);
81 // Getting the function might fail if we're running out of stack or memory.
82 v8::Local<v8::Function> interface_object;
83 bool get_interface_object =
84 interface_template->GetFunction(context).ToLocal(&interface_object);
85 CHECK(get_interface_object);
86
87 if (type->parent_class) {
88 DCHECK(!parent_interface.IsEmpty());
89 bool set_parent_interface =
90 interface_object->SetPrototype(context, parent_interface).ToChecked();
91 CHECK(set_parent_interface);
92 }
93
94 v8::Local<v8::Object> prototype_object;
95 if (type->wrapper_type_prototype ==
96 WrapperTypeInfo::kWrapperTypeObjectPrototype) {
97 v8::Local<v8::Value> prototype_value;
98 bool get_prototype_value =
99 interface_object->Get(context, V8AtomicString(isolate, "prototype"))
100 .ToLocal(&prototype_value);
101 CHECK(get_prototype_value);
102 CHECK(prototype_value->IsObject());
103
104 prototype_object = prototype_value.As<v8::Object>();
105 }
106
107 if (creation_mode == CreationMode::kInstallConditionalFeatures) {
108 type->InstallConditionalFeatures(context, world, v8::Local<v8::Object>(),
109 prototype_object, interface_object,
110 interface_template);
111 InstallOriginTrialFeatures(type, ScriptState::From(context),
112 prototype_object, interface_object);
113 }
114
115 return interface_object;
116 }
117
118 } // namespace blink
119