OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins.h" | 5 #include "src/builtins.h" |
6 | 6 |
7 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 4084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4095 | 4095 |
4096 | 4096 |
4097 // static | 4097 // static |
4098 void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) { | 4098 void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) { |
4099 Generate_DatePrototype_GetField(masm, JSDate::kSecondUTC); | 4099 Generate_DatePrototype_GetField(masm, JSDate::kSecondUTC); |
4100 } | 4100 } |
4101 | 4101 |
4102 | 4102 |
4103 namespace { | 4103 namespace { |
4104 | 4104 |
| 4105 // Walk up the stack expecting: |
| 4106 // - ExitFrame |
| 4107 // - call() (maybe) |
| 4108 // - apply() (maybe) |
| 4109 // - bind() (maybe) |
| 4110 // - JSFunction caller (maybe) |
| 4111 // |
| 4112 // return true if the caller has access to the callee or if an exit frame was |
| 4113 // hit, in which case allow it through, as it could have come through the api. |
| 4114 bool HasAccessToContextForCreateDynamicFunction( |
| 4115 Isolate* isolate, Handle<JSObject> target_global_proxy) { |
| 4116 bool exit_handled = true; |
| 4117 bool has_access = true; |
| 4118 bool done = false; |
| 4119 StackFrameIterator it(isolate); |
| 4120 // Skip exit frame that corresponds to the builtin call. |
| 4121 it.Advance(); |
| 4122 for (; !it.done() && !done; it.Advance()) { |
| 4123 StackFrame* raw_frame = it.frame(); |
| 4124 if (!raw_frame->is_java_script()) { |
| 4125 if (raw_frame->is_exit()) exit_handled = false; |
| 4126 continue; |
| 4127 } |
| 4128 JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame); |
| 4129 List<FrameSummary> frames(FLAG_max_inlining_levels + 1); |
| 4130 outer_frame->Summarize(&frames); |
| 4131 for (int i = frames.length() - 1; i >= 0 && !done; --i) { |
| 4132 FrameSummary& frame = frames[i]; |
| 4133 Handle<JSFunction> fun = frame.function(); |
| 4134 if (!isolate->MayAccess(handle(fun->context()), target_global_proxy)) { |
| 4135 has_access = false; |
| 4136 done = true; |
| 4137 continue; |
| 4138 } |
| 4139 done = true; |
| 4140 } |
| 4141 } |
| 4142 return !exit_handled || has_access; |
| 4143 } |
| 4144 |
4105 // ES6 section 19.2.1.1.1 CreateDynamicFunction | 4145 // ES6 section 19.2.1.1.1 CreateDynamicFunction |
4106 MaybeHandle<JSFunction> CreateDynamicFunction( | 4146 MaybeHandle<Object> CreateDynamicFunction( |
4107 Isolate* isolate, | 4147 Isolate* isolate, |
4108 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args, | 4148 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args, |
4109 const char* token) { | 4149 const char* token) { |
4110 // Compute number of arguments, ignoring the receiver. | 4150 // Compute number of arguments, ignoring the receiver. |
4111 DCHECK_LE(1, args.length()); | 4151 DCHECK_LE(1, args.length()); |
4112 int const argc = args.length() - 1; | 4152 int const argc = args.length() - 1; |
4113 | 4153 |
| 4154 Handle<JSFunction> target = args.target<JSFunction>(); |
| 4155 Handle<JSObject> target_global_proxy(target->global_proxy(), isolate); |
| 4156 |
| 4157 if (!HasAccessToContextForCreateDynamicFunction(isolate, |
| 4158 target_global_proxy)) { |
| 4159 isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined); |
| 4160 return isolate->factory()->undefined_value(); |
| 4161 } |
| 4162 |
4114 // Build the source string. | 4163 // Build the source string. |
4115 Handle<String> source; | 4164 Handle<String> source; |
4116 { | 4165 { |
4117 IncrementalStringBuilder builder(isolate); | 4166 IncrementalStringBuilder builder(isolate); |
4118 builder.AppendCharacter('('); | 4167 builder.AppendCharacter('('); |
4119 builder.AppendCString(token); | 4168 builder.AppendCString(token); |
4120 builder.AppendCharacter('('); | 4169 builder.AppendCharacter('('); |
4121 bool parenthesis_in_arg_string = false; | 4170 bool parenthesis_in_arg_string = false; |
4122 if (argc > 1) { | 4171 if (argc > 1) { |
4123 for (int i = 1; i < argc; ++i) { | 4172 for (int i = 1; i < argc; ++i) { |
4124 if (i > 1) builder.AppendCharacter(','); | 4173 if (i > 1) builder.AppendCharacter(','); |
4125 Handle<String> param; | 4174 Handle<String> param; |
4126 ASSIGN_RETURN_ON_EXCEPTION( | 4175 ASSIGN_RETURN_ON_EXCEPTION( |
4127 isolate, param, Object::ToString(isolate, args.at<Object>(i)), | 4176 isolate, param, Object::ToString(isolate, args.at<Object>(i)), |
4128 JSFunction); | 4177 Object); |
4129 param = String::Flatten(param); | 4178 param = String::Flatten(param); |
4130 builder.AppendString(param); | 4179 builder.AppendString(param); |
4131 // If the formal parameters string include ) - an illegal | 4180 // If the formal parameters string include ) - an illegal |
4132 // character - it may make the combined function expression | 4181 // character - it may make the combined function expression |
4133 // compile. We avoid this problem by checking for this early on. | 4182 // compile. We avoid this problem by checking for this early on. |
4134 DisallowHeapAllocation no_gc; // Ensure vectors stay valid. | 4183 DisallowHeapAllocation no_gc; // Ensure vectors stay valid. |
4135 String::FlatContent param_content = param->GetFlatContent(); | 4184 String::FlatContent param_content = param->GetFlatContent(); |
4136 for (int i = 0, length = param->length(); i < length; ++i) { | 4185 for (int i = 0, length = param->length(); i < length; ++i) { |
4137 if (param_content.Get(i) == ')') { | 4186 if (param_content.Get(i) == ')') { |
4138 parenthesis_in_arg_string = true; | 4187 parenthesis_in_arg_string = true; |
4139 break; | 4188 break; |
4140 } | 4189 } |
4141 } | 4190 } |
4142 } | 4191 } |
4143 // If the formal parameters include an unbalanced block comment, the | 4192 // If the formal parameters include an unbalanced block comment, the |
4144 // function must be rejected. Since JavaScript does not allow nested | 4193 // function must be rejected. Since JavaScript does not allow nested |
4145 // comments we can include a trailing block comment to catch this. | 4194 // comments we can include a trailing block comment to catch this. |
4146 builder.AppendCString("\n/**/"); | 4195 builder.AppendCString("\n/**/"); |
4147 } | 4196 } |
4148 builder.AppendCString(") {\n"); | 4197 builder.AppendCString(") {\n"); |
4149 if (argc > 0) { | 4198 if (argc > 0) { |
4150 Handle<String> body; | 4199 Handle<String> body; |
4151 ASSIGN_RETURN_ON_EXCEPTION( | 4200 ASSIGN_RETURN_ON_EXCEPTION( |
4152 isolate, body, Object::ToString(isolate, args.at<Object>(argc)), | 4201 isolate, body, Object::ToString(isolate, args.at<Object>(argc)), |
4153 JSFunction); | 4202 Object); |
4154 builder.AppendString(body); | 4203 builder.AppendString(body); |
4155 } | 4204 } |
4156 builder.AppendCString("\n})"); | 4205 builder.AppendCString("\n})"); |
4157 ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), JSFunction); | 4206 ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), Object); |
4158 | 4207 |
4159 // The SyntaxError must be thrown after all the (observable) ToString | 4208 // The SyntaxError must be thrown after all the (observable) ToString |
4160 // conversions are done. | 4209 // conversions are done. |
4161 if (parenthesis_in_arg_string) { | 4210 if (parenthesis_in_arg_string) { |
4162 THROW_NEW_ERROR(isolate, | 4211 THROW_NEW_ERROR(isolate, |
4163 NewSyntaxError(MessageTemplate::kParenthesisInArgString), | 4212 NewSyntaxError(MessageTemplate::kParenthesisInArgString), |
4164 JSFunction); | 4213 Object); |
4165 } | 4214 } |
4166 } | 4215 } |
4167 | 4216 |
4168 // Compile the string in the constructor and not a helper so that errors to | 4217 // Compile the string in the constructor and not a helper so that errors to |
4169 // come from here. | 4218 // come from here. |
4170 Handle<JSFunction> target = args.target<JSFunction>(); | |
4171 Handle<JSObject> target_global_proxy(target->global_proxy(), isolate); | |
4172 Handle<JSFunction> function; | 4219 Handle<JSFunction> function; |
4173 { | 4220 { |
4174 ASSIGN_RETURN_ON_EXCEPTION( | 4221 ASSIGN_RETURN_ON_EXCEPTION( |
4175 isolate, function, | 4222 isolate, function, |
4176 CompileString(handle(target->native_context(), isolate), source, | 4223 CompileString(handle(target->native_context(), isolate), source, |
4177 ONLY_SINGLE_FUNCTION_LITERAL), | 4224 ONLY_SINGLE_FUNCTION_LITERAL), |
4178 JSFunction); | 4225 Object); |
4179 Handle<Object> result; | 4226 Handle<Object> result; |
4180 ASSIGN_RETURN_ON_EXCEPTION( | 4227 ASSIGN_RETURN_ON_EXCEPTION( |
4181 isolate, result, | 4228 isolate, result, |
4182 Execution::Call(isolate, function, target_global_proxy, 0, nullptr), | 4229 Execution::Call(isolate, function, target_global_proxy, 0, nullptr), |
4183 JSFunction); | 4230 Object); |
4184 function = Handle<JSFunction>::cast(result); | 4231 function = Handle<JSFunction>::cast(result); |
4185 function->shared()->set_name_should_print_as_anonymous(true); | 4232 function->shared()->set_name_should_print_as_anonymous(true); |
4186 } | 4233 } |
4187 | 4234 |
4188 // If new.target is equal to target then the function created | 4235 // If new.target is equal to target then the function created |
4189 // is already correctly setup and nothing else should be done | 4236 // is already correctly setup and nothing else should be done |
4190 // here. But if new.target is not equal to target then we are | 4237 // here. But if new.target is not equal to target then we are |
4191 // have a Function builtin subclassing case and therefore the | 4238 // have a Function builtin subclassing case and therefore the |
4192 // function has wrong initial map. To fix that we create a new | 4239 // function has wrong initial map. To fix that we create a new |
4193 // function object with correct initial map. | 4240 // function object with correct initial map. |
4194 Handle<Object> unchecked_new_target = args.new_target(); | 4241 Handle<Object> unchecked_new_target = args.new_target(); |
4195 if (!unchecked_new_target->IsUndefined() && | 4242 if (!unchecked_new_target->IsUndefined() && |
4196 !unchecked_new_target.is_identical_to(target)) { | 4243 !unchecked_new_target.is_identical_to(target)) { |
4197 Handle<JSReceiver> new_target = | 4244 Handle<JSReceiver> new_target = |
4198 Handle<JSReceiver>::cast(unchecked_new_target); | 4245 Handle<JSReceiver>::cast(unchecked_new_target); |
4199 Handle<Map> initial_map; | 4246 Handle<Map> initial_map; |
4200 ASSIGN_RETURN_ON_EXCEPTION( | 4247 ASSIGN_RETURN_ON_EXCEPTION( |
4201 isolate, initial_map, | 4248 isolate, initial_map, |
4202 JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction); | 4249 JSFunction::GetDerivedMap(isolate, target, new_target), Object); |
4203 | 4250 |
4204 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate); | 4251 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate); |
4205 Handle<Map> map = Map::AsLanguageMode( | 4252 Handle<Map> map = Map::AsLanguageMode( |
4206 initial_map, shared_info->language_mode(), shared_info->kind()); | 4253 initial_map, shared_info->language_mode(), shared_info->kind()); |
4207 | 4254 |
4208 Handle<Context> context(function->context(), isolate); | 4255 Handle<Context> context(function->context(), isolate); |
4209 function = isolate->factory()->NewFunctionFromSharedFunctionInfo( | 4256 function = isolate->factory()->NewFunctionFromSharedFunctionInfo( |
4210 map, shared_info, context, NOT_TENURED); | 4257 map, shared_info, context, NOT_TENURED); |
4211 } | 4258 } |
4212 return function; | 4259 return function; |
4213 } | 4260 } |
4214 | 4261 |
4215 } // namespace | 4262 } // namespace |
4216 | 4263 |
4217 | 4264 |
4218 // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body ) | 4265 // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body ) |
4219 BUILTIN(FunctionConstructor) { | 4266 BUILTIN(FunctionConstructor) { |
4220 HandleScope scope(isolate); | 4267 HandleScope scope(isolate); |
4221 Handle<JSFunction> result; | 4268 Handle<Object> result; |
4222 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 4269 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
4223 isolate, result, CreateDynamicFunction(isolate, args, "function")); | 4270 isolate, result, CreateDynamicFunction(isolate, args, "function")); |
4224 return *result; | 4271 return *result; |
4225 } | 4272 } |
4226 | 4273 |
4227 | 4274 |
4228 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) | 4275 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) |
4229 BUILTIN(FunctionPrototypeBind) { | 4276 BUILTIN(FunctionPrototypeBind) { |
4230 HandleScope scope(isolate); | 4277 HandleScope scope(isolate); |
4231 DCHECK_LE(1, args.length()); | 4278 DCHECK_LE(1, args.length()); |
(...skipping 1561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5793 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 5840 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
5794 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 5841 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
5795 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 5842 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
5796 #undef DEFINE_BUILTIN_ACCESSOR_C | 5843 #undef DEFINE_BUILTIN_ACCESSOR_C |
5797 #undef DEFINE_BUILTIN_ACCESSOR_A | 5844 #undef DEFINE_BUILTIN_ACCESSOR_A |
5798 #undef DEFINE_BUILTIN_ACCESSOR_T | 5845 #undef DEFINE_BUILTIN_ACCESSOR_T |
5799 #undef DEFINE_BUILTIN_ACCESSOR_H | 5846 #undef DEFINE_BUILTIN_ACCESSOR_H |
5800 | 5847 |
5801 } // namespace internal | 5848 } // namespace internal |
5802 } // namespace v8 | 5849 } // namespace v8 |
OLD | NEW |