| 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 |