| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2016 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. | 
|  | 4 | 
|  | 5 #include "src/builtins/builtins.h" | 
|  | 6 #include "src/builtins/builtins-utils.h" | 
|  | 7 | 
|  | 8 #include "src/string-builder.h" | 
|  | 9 #include "src/wasm/wasm-module.h" | 
|  | 10 | 
|  | 11 namespace v8 { | 
|  | 12 namespace internal { | 
|  | 13 | 
|  | 14 #define CHECK_CALLSITE(recv, method)                                          \ | 
|  | 15   CHECK_RECEIVER(JSObject, recv, method);                                     \ | 
|  | 16   if (!JSReceiver::HasOwnProperty(                                            \ | 
|  | 17            recv, isolate->factory()->call_site_position_symbol())             \ | 
|  | 18            .FromMaybe(false)) {                                               \ | 
|  | 19     THROW_NEW_ERROR_RETURN_FAILURE(                                           \ | 
|  | 20         isolate,                                                              \ | 
|  | 21         NewTypeError(MessageTemplate::kCallSiteMethod,                        \ | 
|  | 22                      isolate->factory()->NewStringFromAsciiChecked(method))); \ | 
|  | 23   } | 
|  | 24 | 
|  | 25 #define SET_CALLSITE_PROPERTY(target, key, value)        \ | 
|  | 26   RETURN_FAILURE_ON_EXCEPTION(                           \ | 
|  | 27       isolate, JSObject::SetOwnPropertyIgnoreAttributes( \ | 
|  | 28                    target, isolate->factory()->key(), value, DONT_ENUM)) | 
|  | 29 | 
|  | 30 BUILTIN(CallSiteConstructor) { | 
|  | 31   HandleScope scope(isolate); | 
|  | 32   Handle<JSFunction> target = args.target<JSFunction>(); | 
|  | 33   Handle<HeapObject> new_target_obj = args.new_target(); | 
|  | 34   Handle<Object> receiver = args.atOrUndefined(isolate, 1); | 
|  | 35   Handle<Object> fun = args.atOrUndefined(isolate, 2); | 
|  | 36   Handle<Object> pos = args.atOrUndefined(isolate, 3); | 
|  | 37   Handle<Object> strict_mode = args.atOrUndefined(isolate, 4); | 
|  | 38 | 
|  | 39   // Create the JS object. | 
|  | 40 | 
|  | 41   Handle<JSReceiver> new_target = new_target_obj->IsJSReceiver() | 
|  | 42                                       ? Handle<JSReceiver>::cast(new_target_obj) | 
|  | 43                                       : Handle<JSReceiver>::cast(target); | 
|  | 44 | 
|  | 45   Handle<JSObject> obj; | 
|  | 46   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, obj, | 
|  | 47                                      JSObject::New(target, new_target)); | 
|  | 48 | 
|  | 49   // For wasm frames, receiver is the wasm object and fun is the function index | 
|  | 50   // instead of an actual function. | 
|  | 51   const bool is_wasm_object = | 
|  | 52       receiver->IsJSObject() && wasm::IsWasmObject(JSObject::cast(*receiver)); | 
|  | 53   if (!fun->IsJSFunction() && !is_wasm_object) { | 
|  | 54     THROW_NEW_ERROR_RETURN_FAILURE( | 
|  | 55         isolate, NewTypeError(MessageTemplate::kCallSiteExpectsFunction, | 
|  | 56                               Object::TypeOf(isolate, receiver), | 
|  | 57                               Object::TypeOf(isolate, fun))); | 
|  | 58   } | 
|  | 59 | 
|  | 60   if (is_wasm_object) { | 
|  | 61     DCHECK(!fun->IsJSFunction()); | 
|  | 62     SET_CALLSITE_PROPERTY(obj, call_site_wasm_obj_symbol, receiver); | 
|  | 63 | 
|  | 64     Handle<Object> fun_index; | 
|  | 65     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, fun_index, | 
|  | 66                                        Object::ToUint32(isolate, fun)); | 
|  | 67     SET_CALLSITE_PROPERTY(obj, call_site_wasm_func_index_symbol, fun); | 
|  | 68   } else { | 
|  | 69     DCHECK(fun->IsJSFunction()); | 
|  | 70     SET_CALLSITE_PROPERTY(obj, call_site_receiver_symbol, receiver); | 
|  | 71     SET_CALLSITE_PROPERTY(obj, call_site_function_symbol, fun); | 
|  | 72   } | 
|  | 73 | 
|  | 74   Handle<Object> pos_int32; | 
|  | 75   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, pos_int32, | 
|  | 76                                      Object::ToInt32(isolate, pos)); | 
|  | 77   SET_CALLSITE_PROPERTY(obj, call_site_position_symbol, pos_int32); | 
|  | 78   SET_CALLSITE_PROPERTY( | 
|  | 79       obj, call_site_strict_symbol, | 
|  | 80       isolate->factory()->ToBoolean(strict_mode->BooleanValue())); | 
|  | 81 | 
|  | 82   return *obj; | 
|  | 83 } | 
|  | 84 | 
|  | 85 #undef SET_CALLSITE_PROPERTY | 
|  | 86 | 
|  | 87 namespace { | 
|  | 88 | 
|  | 89 Object* PositiveNumberOrNull(int value, Isolate* isolate) { | 
|  | 90   if (value >= 0) return *isolate->factory()->NewNumberFromInt(value); | 
|  | 91   return isolate->heap()->null_value(); | 
|  | 92 } | 
|  | 93 | 
|  | 94 }  // namespace | 
|  | 95 | 
|  | 96 BUILTIN(CallSitePrototypeGetColumnNumber) { | 
|  | 97   HandleScope scope(isolate); | 
|  | 98   CHECK_CALLSITE(recv, "getColumnNumber"); | 
|  | 99 | 
|  | 100   CallSite call_site(isolate, recv); | 
|  | 101   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 102   return PositiveNumberOrNull(call_site.GetColumnNumber(), isolate); | 
|  | 103 } | 
|  | 104 | 
|  | 105 namespace { | 
|  | 106 | 
|  | 107 Object* EvalFromFunctionName(Isolate* isolate, Handle<Script> script) { | 
|  | 108   if (script->eval_from_shared()->IsUndefined(isolate)) | 
|  | 109     return *isolate->factory()->undefined_value(); | 
|  | 110 | 
|  | 111   Handle<SharedFunctionInfo> shared( | 
|  | 112       SharedFunctionInfo::cast(script->eval_from_shared())); | 
|  | 113   // Find the name of the function calling eval. | 
|  | 114   if (shared->name()->BooleanValue()) { | 
|  | 115     return shared->name(); | 
|  | 116   } | 
|  | 117 | 
|  | 118   return shared->inferred_name(); | 
|  | 119 } | 
|  | 120 | 
|  | 121 Object* EvalFromScript(Isolate* isolate, Handle<Script> script) { | 
|  | 122   if (script->eval_from_shared()->IsUndefined(isolate)) | 
|  | 123     return *isolate->factory()->undefined_value(); | 
|  | 124 | 
|  | 125   Handle<SharedFunctionInfo> eval_from_shared( | 
|  | 126       SharedFunctionInfo::cast(script->eval_from_shared())); | 
|  | 127   return eval_from_shared->script()->IsScript() | 
|  | 128              ? eval_from_shared->script() | 
|  | 129              : *isolate->factory()->undefined_value(); | 
|  | 130 } | 
|  | 131 | 
|  | 132 MaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) { | 
|  | 133   Handle<Object> sourceURL = Script::GetNameOrSourceURL(script); | 
|  | 134   if (!sourceURL->IsUndefined(isolate)) { | 
|  | 135     DCHECK(sourceURL->IsString()); | 
|  | 136     return Handle<String>::cast(sourceURL); | 
|  | 137   } | 
|  | 138 | 
|  | 139   IncrementalStringBuilder builder(isolate); | 
|  | 140   builder.AppendCString("eval at "); | 
|  | 141 | 
|  | 142   Handle<Object> eval_from_function_name = | 
|  | 143       handle(EvalFromFunctionName(isolate, script), isolate); | 
|  | 144   if (eval_from_function_name->BooleanValue()) { | 
|  | 145     Handle<String> str; | 
|  | 146     ASSIGN_RETURN_ON_EXCEPTION( | 
|  | 147         isolate, str, Object::ToString(isolate, eval_from_function_name), | 
|  | 148         String); | 
|  | 149     builder.AppendString(str); | 
|  | 150   } else { | 
|  | 151     builder.AppendCString("<anonymous>"); | 
|  | 152   } | 
|  | 153 | 
|  | 154   Handle<Object> eval_from_script_obj = | 
|  | 155       handle(EvalFromScript(isolate, script), isolate); | 
|  | 156   if (eval_from_script_obj->IsScript()) { | 
|  | 157     Handle<Script> eval_from_script = | 
|  | 158         Handle<Script>::cast(eval_from_script_obj); | 
|  | 159     builder.AppendCString(" ("); | 
|  | 160     if (eval_from_script->compilation_type() == Script::COMPILATION_TYPE_EVAL) { | 
|  | 161       // Eval script originated from another eval. | 
|  | 162       Handle<String> str; | 
|  | 163       ASSIGN_RETURN_ON_EXCEPTION( | 
|  | 164           isolate, str, FormatEvalOrigin(isolate, eval_from_script), String); | 
|  | 165       builder.AppendString(str); | 
|  | 166     } else { | 
|  | 167       DCHECK(eval_from_script->compilation_type() != | 
|  | 168              Script::COMPILATION_TYPE_EVAL); | 
|  | 169       // eval script originated from "real" source. | 
|  | 170       Handle<Object> name_obj = handle(eval_from_script->name(), isolate); | 
|  | 171       if (eval_from_script->name()->IsString()) { | 
|  | 172         builder.AppendString(Handle<String>::cast(name_obj)); | 
|  | 173 | 
|  | 174         Script::PositionInfo info; | 
|  | 175         if (eval_from_script->GetPositionInfo(script->GetEvalPosition(), &info, | 
|  | 176                                               Script::NO_OFFSET)) { | 
|  | 177           builder.AppendCString(":"); | 
|  | 178 | 
|  | 179           Handle<String> str = isolate->factory()->NumberToString( | 
|  | 180               handle(Smi::FromInt(info.line + 1), isolate)); | 
|  | 181           builder.AppendString(str); | 
|  | 182 | 
|  | 183           builder.AppendCString(":"); | 
|  | 184 | 
|  | 185           str = isolate->factory()->NumberToString( | 
|  | 186               handle(Smi::FromInt(info.column + 1), isolate)); | 
|  | 187           builder.AppendString(str); | 
|  | 188         } | 
|  | 189       } else { | 
|  | 190         DCHECK(!eval_from_script->name()->IsString()); | 
|  | 191         builder.AppendCString("unknown source"); | 
|  | 192       } | 
|  | 193     } | 
|  | 194     builder.AppendCString(")"); | 
|  | 195   } | 
|  | 196 | 
|  | 197   Handle<String> result; | 
|  | 198   ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String); | 
|  | 199   return result; | 
|  | 200 } | 
|  | 201 | 
|  | 202 }  // namespace | 
|  | 203 | 
|  | 204 BUILTIN(CallSitePrototypeGetEvalOrigin) { | 
|  | 205   HandleScope scope(isolate); | 
|  | 206   CHECK_CALLSITE(recv, "getEvalOrigin"); | 
|  | 207 | 
|  | 208   CallSite call_site(isolate, recv); | 
|  | 209   if (call_site.IsWasm()) return *isolate->factory()->undefined_value(); | 
|  | 210 | 
|  | 211   // Retrieve the function's script object. | 
|  | 212 | 
|  | 213   Handle<Object> function_obj; | 
|  | 214   Handle<Symbol> symbol = isolate->factory()->call_site_function_symbol(); | 
|  | 215   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, function_obj, | 
|  | 216                                      JSObject::GetProperty(recv, symbol)); | 
|  | 217 | 
|  | 218   DCHECK(function_obj->IsJSFunction()); | 
|  | 219   Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj); | 
|  | 220   Handle<Object> script = handle(function->shared()->script(), isolate); | 
|  | 221 | 
|  | 222   RETURN_RESULT_OR_FAILURE( | 
|  | 223       isolate, FormatEvalOrigin(isolate, Handle<Script>::cast(script))); | 
|  | 224 } | 
|  | 225 | 
|  | 226 BUILTIN(CallSitePrototypeGetFileName) { | 
|  | 227   HandleScope scope(isolate); | 
|  | 228   CHECK_CALLSITE(recv, "getFileName"); | 
|  | 229 | 
|  | 230   CallSite call_site(isolate, recv); | 
|  | 231   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 232   return *call_site.GetFileName(); | 
|  | 233 } | 
|  | 234 | 
|  | 235 namespace { | 
|  | 236 | 
|  | 237 bool CallSiteIsStrict(Isolate* isolate, Handle<JSObject> receiver) { | 
|  | 238   Handle<Object> strict; | 
|  | 239   Handle<Symbol> symbol = isolate->factory()->call_site_strict_symbol(); | 
|  | 240   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, strict, | 
|  | 241                                      JSObject::GetProperty(receiver, symbol)); | 
|  | 242   return strict->BooleanValue(); | 
|  | 243 } | 
|  | 244 | 
|  | 245 }  // namespace | 
|  | 246 | 
|  | 247 BUILTIN(CallSitePrototypeGetFunction) { | 
|  | 248   HandleScope scope(isolate); | 
|  | 249   CHECK_CALLSITE(recv, "getFunction"); | 
|  | 250 | 
|  | 251   if (CallSiteIsStrict(isolate, recv)) | 
|  | 252     return *isolate->factory()->undefined_value(); | 
|  | 253 | 
|  | 254   Handle<Symbol> symbol = isolate->factory()->call_site_function_symbol(); | 
|  | 255   RETURN_RESULT_OR_FAILURE(isolate, JSObject::GetProperty(recv, symbol)); | 
|  | 256 } | 
|  | 257 | 
|  | 258 BUILTIN(CallSitePrototypeGetFunctionName) { | 
|  | 259   HandleScope scope(isolate); | 
|  | 260   CHECK_CALLSITE(recv, "getFunctionName"); | 
|  | 261 | 
|  | 262   CallSite call_site(isolate, recv); | 
|  | 263   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 264   return *call_site.GetFunctionName(); | 
|  | 265 } | 
|  | 266 | 
|  | 267 BUILTIN(CallSitePrototypeGetLineNumber) { | 
|  | 268   HandleScope scope(isolate); | 
|  | 269   CHECK_CALLSITE(recv, "getLineNumber"); | 
|  | 270 | 
|  | 271   CallSite call_site(isolate, recv); | 
|  | 272   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 273 | 
|  | 274   int line_number = call_site.IsWasm() ? call_site.wasm_func_index() | 
|  | 275                                        : call_site.GetLineNumber(); | 
|  | 276   return PositiveNumberOrNull(line_number, isolate); | 
|  | 277 } | 
|  | 278 | 
|  | 279 BUILTIN(CallSitePrototypeGetMethodName) { | 
|  | 280   HandleScope scope(isolate); | 
|  | 281   CHECK_CALLSITE(recv, "getMethodName"); | 
|  | 282 | 
|  | 283   CallSite call_site(isolate, recv); | 
|  | 284   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 285   return *call_site.GetMethodName(); | 
|  | 286 } | 
|  | 287 | 
|  | 288 BUILTIN(CallSitePrototypeGetPosition) { | 
|  | 289   HandleScope scope(isolate); | 
|  | 290   CHECK_CALLSITE(recv, "getPosition"); | 
|  | 291 | 
|  | 292   Handle<Symbol> symbol = isolate->factory()->call_site_position_symbol(); | 
|  | 293   RETURN_RESULT_OR_FAILURE(isolate, JSObject::GetProperty(recv, symbol)); | 
|  | 294 } | 
|  | 295 | 
|  | 296 BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) { | 
|  | 297   HandleScope scope(isolate); | 
|  | 298   CHECK_CALLSITE(recv, "getScriptNameOrSourceUrl"); | 
|  | 299 | 
|  | 300   CallSite call_site(isolate, recv); | 
|  | 301   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 302   return *call_site.GetScriptNameOrSourceUrl(); | 
|  | 303 } | 
|  | 304 | 
|  | 305 BUILTIN(CallSitePrototypeGetThis) { | 
|  | 306   HandleScope scope(isolate); | 
|  | 307   CHECK_CALLSITE(recv, "getThis"); | 
|  | 308 | 
|  | 309   if (CallSiteIsStrict(isolate, recv)) | 
|  | 310     return *isolate->factory()->undefined_value(); | 
|  | 311 | 
|  | 312   Handle<Object> receiver; | 
|  | 313   Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); | 
|  | 314   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
|  | 315                                      JSObject::GetProperty(recv, symbol)); | 
|  | 316 | 
|  | 317   if (*receiver == isolate->heap()->call_site_constructor_symbol()) | 
|  | 318     return *isolate->factory()->undefined_value(); | 
|  | 319 | 
|  | 320   return *receiver; | 
|  | 321 } | 
|  | 322 | 
|  | 323 BUILTIN(CallSitePrototypeGetTypeName) { | 
|  | 324   HandleScope scope(isolate); | 
|  | 325   CHECK_CALLSITE(recv, "getTypeName"); | 
|  | 326 | 
|  | 327   Handle<Object> receiver; | 
|  | 328   Handle<Symbol> symbol = isolate->factory()->call_site_receiver_symbol(); | 
|  | 329   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, | 
|  | 330                                      JSObject::GetProperty(recv, symbol)); | 
|  | 331 | 
|  | 332   // TODO(jgruber): Check for strict/constructor here as above. | 
|  | 333 | 
|  | 334   if (receiver->IsNull(isolate) || receiver->IsUndefined(isolate)) | 
|  | 335     return *isolate->factory()->null_value(); | 
|  | 336 | 
|  | 337   if (receiver->IsJSProxy()) return *isolate->factory()->Proxy_string(); | 
|  | 338 | 
|  | 339   Handle<JSReceiver> receiver_object = | 
|  | 340       Object::ToObject(isolate, receiver).ToHandleChecked(); | 
|  | 341   return *JSReceiver::GetConstructorName(receiver_object); | 
|  | 342 } | 
|  | 343 | 
|  | 344 BUILTIN(CallSitePrototypeIsConstructor) { | 
|  | 345   HandleScope scope(isolate); | 
|  | 346   CHECK_CALLSITE(recv, "isConstructor"); | 
|  | 347 | 
|  | 348   CallSite call_site(isolate, recv); | 
|  | 349   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 350   return isolate->heap()->ToBoolean(call_site.IsConstructor()); | 
|  | 351 } | 
|  | 352 | 
|  | 353 BUILTIN(CallSitePrototypeIsEval) { | 
|  | 354   HandleScope scope(isolate); | 
|  | 355   CHECK_CALLSITE(recv, "isEval"); | 
|  | 356 | 
|  | 357   CallSite call_site(isolate, recv); | 
|  | 358   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 359   return isolate->heap()->ToBoolean(call_site.IsEval()); | 
|  | 360 } | 
|  | 361 | 
|  | 362 BUILTIN(CallSitePrototypeIsNative) { | 
|  | 363   HandleScope scope(isolate); | 
|  | 364   CHECK_CALLSITE(recv, "isNative"); | 
|  | 365 | 
|  | 366   CallSite call_site(isolate, recv); | 
|  | 367   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 368   return isolate->heap()->ToBoolean(call_site.IsNative()); | 
|  | 369 } | 
|  | 370 | 
|  | 371 BUILTIN(CallSitePrototypeIsToplevel) { | 
|  | 372   HandleScope scope(isolate); | 
|  | 373   CHECK_CALLSITE(recv, "isToplevel"); | 
|  | 374 | 
|  | 375   CallSite call_site(isolate, recv); | 
|  | 376   CHECK(call_site.IsJavaScript() || call_site.IsWasm()); | 
|  | 377   return isolate->heap()->ToBoolean(call_site.IsToplevel()); | 
|  | 378 } | 
|  | 379 | 
|  | 380 BUILTIN(CallSitePrototypeToString) { | 
|  | 381   HandleScope scope(isolate); | 
|  | 382   // TODO(jgruber) | 
|  | 383   return *isolate->factory()->undefined_value(); | 
|  | 384 } | 
|  | 385 | 
|  | 386 #undef CHECK_CALLSITE | 
|  | 387 | 
|  | 388 }  // namespace internal | 
|  | 389 }  // namespace v8 | 
| OLD | NEW | 
|---|