| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/api.h" | 5 #include "src/api.h" |
| 6 #include "src/api-natives.h" | 6 #include "src/api-natives.h" |
| 7 #include "src/assert-scope.h" | 7 #include "src/assert-scope.h" |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 namespace v8 { | 28 namespace v8 { |
| 29 | 29 |
| 30 namespace { | 30 namespace { |
| 31 struct RawBuffer { | 31 struct RawBuffer { |
| 32 const byte* start; | 32 const byte* start; |
| 33 const byte* end; | 33 const byte* end; |
| 34 size_t size() { return static_cast<size_t>(end - start); } | 34 size_t size() { return static_cast<size_t>(end - start); } |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 | |
| 38 RawBuffer GetRawBufferArgument( | 37 RawBuffer GetRawBufferArgument( |
| 39 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { | 38 ErrorThrower& thrower, const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 40 if (args.Length() < 1) { | 39 if (args.Length() < 1) { |
| 41 thrower.Error("Argument 0 must be an array buffer"); | 40 thrower.Error("Argument 0 must be an array buffer"); |
| 42 return {nullptr, nullptr}; | 41 return {nullptr, nullptr}; |
| 43 } | 42 } |
| 44 | 43 |
| 45 const byte* start = nullptr; | 44 const byte* start = nullptr; |
| 46 const byte* end = nullptr; | 45 const byte* end = nullptr; |
| 47 | 46 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 70 if (start == nullptr || end == start) { | 69 if (start == nullptr || end == start) { |
| 71 thrower.Error("ArrayBuffer argument is empty"); | 70 thrower.Error("ArrayBuffer argument is empty"); |
| 72 } | 71 } |
| 73 } else { | 72 } else { |
| 74 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); | 73 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); |
| 75 } | 74 } |
| 76 | 75 |
| 77 return {start, end}; | 76 return {start, end}; |
| 78 } | 77 } |
| 79 | 78 |
| 80 | |
| 81 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 79 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 82 HandleScope scope(args.GetIsolate()); | 80 HandleScope scope(args.GetIsolate()); |
| 83 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 81 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
| 84 ErrorThrower thrower(isolate, "WASM.verifyModule()"); | 82 ErrorThrower thrower(isolate, "WASM.verifyModule()"); |
| 85 | 83 |
| 86 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 84 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
| 87 if (thrower.error()) return; | 85 if (thrower.error()) return; |
| 88 | 86 |
| 89 i::Zone zone(isolate->allocator()); | 87 i::Zone zone(isolate->allocator()); |
| 90 internal::wasm::ModuleResult result = | 88 internal::wasm::ModuleResult result = |
| 91 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, | 89 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, |
| 92 true, internal::wasm::kWasmOrigin); | 90 true, internal::wasm::kWasmOrigin); |
| 93 | 91 |
| 94 if (result.failed()) { | 92 if (result.failed()) { |
| 95 thrower.Failed("", result); | 93 thrower.Failed("", result); |
| 96 } | 94 } |
| 97 | 95 |
| 98 if (result.val) delete result.val; | 96 if (result.val) delete result.val; |
| 99 } | 97 } |
| 100 | 98 |
| 101 | |
| 102 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { | 99 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 103 HandleScope scope(args.GetIsolate()); | 100 HandleScope scope(args.GetIsolate()); |
| 104 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 101 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
| 105 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); | 102 ErrorThrower thrower(isolate, "WASM.verifyFunction()"); |
| 106 | 103 |
| 107 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 104 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
| 108 if (thrower.error()) return; | 105 if (thrower.error()) return; |
| 109 | 106 |
| 110 internal::wasm::FunctionResult result; | 107 internal::wasm::FunctionResult result; |
| 111 { | 108 { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 result.val->Instantiate(isolate, ffi, memory); | 192 result.val->Instantiate(isolate, ffi, memory); |
| 196 | 193 |
| 197 if (!object.is_null()) { | 194 if (!object.is_null()) { |
| 198 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | 195 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); |
| 199 } | 196 } |
| 200 } | 197 } |
| 201 | 198 |
| 202 if (result.val) delete result.val; | 199 if (result.val) delete result.val; |
| 203 } | 200 } |
| 204 | 201 |
| 205 | |
| 206 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { | 202 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 207 HandleScope scope(args.GetIsolate()); | 203 HandleScope scope(args.GetIsolate()); |
| 208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 204 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
| 209 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); | 205 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); |
| 210 | 206 |
| 211 if (!args[0]->IsString()) { | 207 if (!args[0]->IsString()) { |
| 212 thrower.Error("Asm module text should be a string"); | 208 thrower.Error("Asm module text should be a string"); |
| 213 return; | 209 return; |
| 214 } | 210 } |
| 215 | 211 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 227 | 223 |
| 228 auto module = TranslateAsmModule(&info, foreign, &thrower); | 224 auto module = TranslateAsmModule(&info, foreign, &thrower); |
| 229 if (module == nullptr) { | 225 if (module == nullptr) { |
| 230 return; | 226 return; |
| 231 } | 227 } |
| 232 | 228 |
| 233 InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, | 229 InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, |
| 234 internal::wasm::kAsmJsOrigin); | 230 internal::wasm::kAsmJsOrigin); |
| 235 } | 231 } |
| 236 | 232 |
| 237 | |
| 238 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 233 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 239 HandleScope scope(args.GetIsolate()); | 234 HandleScope scope(args.GetIsolate()); |
| 240 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 235 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
| 241 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); | 236 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); |
| 242 | 237 |
| 243 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 238 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
| 244 if (buffer.start == nullptr) return; | 239 if (buffer.start == nullptr) return; |
| 245 | 240 |
| 246 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, | 241 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, |
| 247 internal::wasm::kWasmOrigin); | 242 internal::wasm::kWasmOrigin); |
| 248 } | 243 } |
| 249 } // namespace | 244 } // namespace |
| 250 | 245 |
| 251 | |
| 252 // TODO(titzer): we use the API to create the function template because the | 246 // TODO(titzer): we use the API to create the function template because the |
| 253 // internal guts are too ugly to replicate here. | 247 // internal guts are too ugly to replicate here. |
| 254 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, | 248 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, |
| 255 FunctionCallback func) { | 249 FunctionCallback func) { |
| 256 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); | 250 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); |
| 257 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); | 251 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); |
| 258 return v8::Utils::OpenHandle(*local); | 252 return v8::Utils::OpenHandle(*local); |
| 259 } | 253 } |
| 260 | 254 |
| 261 | |
| 262 namespace internal { | 255 namespace internal { |
| 263 static Handle<String> v8_str(Isolate* isolate, const char* str) { | 256 static Handle<String> v8_str(Isolate* isolate, const char* str) { |
| 264 return isolate->factory()->NewStringFromAsciiChecked(str); | 257 return isolate->factory()->NewStringFromAsciiChecked(str); |
| 265 } | 258 } |
| 266 | 259 |
| 267 | |
| 268 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, | 260 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, |
| 269 const char* str, FunctionCallback func) { | 261 const char* str, FunctionCallback func) { |
| 270 Handle<String> name = v8_str(isolate, str); | 262 Handle<String> name = v8_str(isolate, str); |
| 271 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 263 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
| 272 Handle<JSFunction> function = | 264 Handle<JSFunction> function = |
| 273 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 265 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
| 274 PropertyAttributes attributes = | 266 PropertyAttributes attributes = |
| 275 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 267 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 276 JSObject::AddProperty(object, name, function, attributes); | 268 JSObject::AddProperty(object, name, function, attributes); |
| 277 } | 269 } |
| 278 | 270 |
| 279 | |
| 280 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 271 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
| 281 // Setup wasm function map. | 272 // Setup wasm function map. |
| 282 Handle<Context> context(global->native_context(), isolate); | 273 Handle<Context> context(global->native_context(), isolate); |
| 283 InstallWasmFunctionMap(isolate, context); | 274 InstallWasmFunctionMap(isolate, context); |
| 284 | 275 |
| 285 // Bind the WASM object. | 276 // Bind the WASM object. |
| 286 Factory* factory = isolate->factory(); | 277 Factory* factory = isolate->factory(); |
| 287 Handle<String> name = v8_str(isolate, "Wasm"); | 278 Handle<String> name = v8_str(isolate, "Wasm"); |
| 288 Handle<JSFunction> cons = factory->NewFunction(name); | 279 Handle<JSFunction> cons = factory->NewFunction(name); |
| 289 JSFunction::SetInstancePrototype( | 280 JSFunction::SetInstancePrototype( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 303 { | 294 { |
| 304 // Add the Wasm.experimentalVersion property. | 295 // Add the Wasm.experimentalVersion property. |
| 305 Handle<String> name = v8_str(isolate, "experimentalVersion"); | 296 Handle<String> name = v8_str(isolate, "experimentalVersion"); |
| 306 PropertyAttributes attributes = | 297 PropertyAttributes attributes = |
| 307 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 298 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 308 Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); | 299 Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); |
| 309 JSObject::AddProperty(wasm_object, name, value, attributes); | 300 JSObject::AddProperty(wasm_object, name, value, attributes); |
| 310 } | 301 } |
| 311 } | 302 } |
| 312 | 303 |
| 313 | |
| 314 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { | 304 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { |
| 315 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | 305 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
| 316 // TODO(titzer): Move this to bootstrapper.cc?? | 306 // TODO(titzer): Move this to bootstrapper.cc?? |
| 317 // TODO(titzer): Also make one for strict mode functions? | 307 // TODO(titzer): Also make one for strict mode functions? |
| 318 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | 308 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
| 319 | 309 |
| 320 InstanceType instance_type = prev_map->instance_type(); | 310 InstanceType instance_type = prev_map->instance_type(); |
| 321 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); | 311 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
| 322 CHECK_EQ(0, internal_fields); | 312 CHECK_EQ(0, internal_fields); |
| 323 int pre_allocated = | 313 int pre_allocated = |
| 324 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); | 314 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); |
| 325 int instance_size; | 315 int instance_size; |
| 326 int in_object_properties; | 316 int in_object_properties; |
| 327 JSFunction::CalculateInstanceSizeHelper(instance_type, internal_fields + 1, | 317 JSFunction::CalculateInstanceSizeHelper(instance_type, internal_fields + 1, |
| 328 0, &instance_size, | 318 0, &instance_size, |
| 329 &in_object_properties); | 319 &in_object_properties); |
| 330 | 320 |
| 331 int unused_property_fields = in_object_properties - pre_allocated; | 321 int unused_property_fields = in_object_properties - pre_allocated; |
| 332 Handle<Map> map = Map::CopyInitialMap( | 322 Handle<Map> map = Map::CopyInitialMap( |
| 333 prev_map, instance_size, in_object_properties, unused_property_fields); | 323 prev_map, instance_size, in_object_properties, unused_property_fields); |
| 334 | 324 |
| 335 context->set_wasm_function_map(*map); | 325 context->set_wasm_function_map(*map); |
| 336 } | 326 } |
| 337 } | 327 } |
| 338 | 328 |
| 339 } // namespace internal | 329 } // namespace internal |
| 340 } // namespace v8 | 330 } // namespace v8 |
| OLD | NEW |