├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── DartQuickjsPlugin.h │ ├── SwiftDartQuickjsPlugin.swift │ └── DartQuickjsPlugin.m ├── .gitignore ├── dart_quickjs.podspec └── cxx │ ├── libregexp-opcode.h │ ├── quickjs-libc.h │ ├── libregexp.h │ ├── list.h │ ├── ffi.h │ └── libunicode.h ├── cxx ├── quickjs │ ├── test262o_errors.txt │ ├── VERSION │ ├── examples │ │ ├── hello.js │ │ ├── hello_module.js │ │ ├── test_fib.js │ │ ├── fib_module.js │ │ ├── test_point.js │ │ ├── pi_bigfloat.js │ │ ├── pi_bigdecimal.js │ │ ├── fib.c │ │ ├── pi_bigint.js │ │ └── point.c │ ├── readme.txt │ ├── unicode_download.sh │ ├── tests │ │ ├── test_worker_module.js │ │ ├── test_worker.js │ │ ├── test262.patch │ │ ├── bjson.c │ │ └── test_closure.js │ ├── LICENSE │ ├── libregexp-opcode.h │ ├── quickjs-libc.h │ ├── TODO │ ├── libregexp.h │ ├── list.h │ ├── release.sh │ ├── libunicode.h │ ├── Changelog │ └── test262.conf ├── CMakeLists.txt ├── prebuild.sh └── ffi.h ├── android ├── settings.gradle ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── com │ │ └── allan │ │ └── dart_quickjs │ │ └── DartQuickjsPlugin.kt ├── CMakeLists.txt └── build.gradle ├── example ├── assets │ ├── main.js │ └── main.bin ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile.lock │ └── Podfile ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── allan │ │ │ │ │ │ └── dart_quickjs_example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── macos │ ├── Runner │ │ ├── Configs │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ ├── Warnings.xcconfig │ │ │ └── AppInfo.xcconfig │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app_icon_1024.png │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_512.png │ │ │ │ ├── app_icon_64.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Release.entitlements │ │ ├── DebugProfile.entitlements │ │ ├── MainFlutterWindow.swift │ │ └── Info.plist │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Podfile.lock │ └── Podfile ├── README.md ├── .gitignore ├── .metadata ├── analysis_options.yaml ├── lib │ └── main.dart └── pubspec.yaml ├── lib ├── src │ ├── plugin.dart │ ├── library.dart │ ├── cache.dart │ ├── observer.dart │ ├── common.dart │ ├── extensions.dart │ ├── typedef.dart │ └── plugins │ │ └── timer.dart └── dart_quickjs.dart ├── analysis_options.yaml ├── macos ├── Classes │ └── DartQuickjsPlugin.swift ├── dart_quickjs.podspec └── cxx │ ├── libregexp-opcode.h │ ├── quickjs-libc.h │ ├── libregexp.h │ ├── list.h │ ├── libunicode.h │ └── ffi.h ├── .gitignore ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── .metadata ├── pubspec.yaml └── README-ZH.md /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cxx/quickjs/test262o_errors.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cxx/quickjs/VERSION: -------------------------------------------------------------------------------- 1 | 2021-03-27 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'dart_quickjs' 2 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/hello.js: -------------------------------------------------------------------------------- 1 | console.log("Hello World"); 2 | -------------------------------------------------------------------------------- /example/assets/main.js: -------------------------------------------------------------------------------- 1 | function test() {} 2 | 3 | test; 4 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /cxx/quickjs/readme.txt: -------------------------------------------------------------------------------- 1 | The main documentation is in doc/quickjs.pdf or doc/quickjs.html. 2 | -------------------------------------------------------------------------------- /example/assets/main.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/assets/main.bin -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Classes/DartQuickjsPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface DartQuickjsPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /lib/src/plugin.dart: -------------------------------------------------------------------------------- 1 | import 'runtime.dart'; 2 | 3 | abstract class Plugin { 4 | void onCreate(Runtime runtime); 5 | 6 | void destroy(Runtime runtime) {} 7 | } 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/hello_module.js: -------------------------------------------------------------------------------- 1 | /* example of JS module */ 2 | 3 | import { fib } from "./fib_module.js"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/test_fib.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | 3 | import { fib } from "./fib.so"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allan-hx/dart_quickjs/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/allan/dart_quickjs_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.allan.dart_quickjs_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/fib_module.js: -------------------------------------------------------------------------------- 1 | /* fib module */ 2 | export function fib(n) 3 | { 4 | if (n <= 0) 5 | return 0; 6 | else if (n == 1) 7 | return 1; 8 | else 9 | return fib(n - 1) + fib(n - 2); 10 | } 11 | -------------------------------------------------------------------------------- /lib/src/library.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | import 'dart:io'; 3 | import 'bindings.dart'; 4 | 5 | final library = QuickjsLibrary( 6 | Platform.isAndroid 7 | ? DynamicLibrary.open('libquickjs.so') 8 | : DynamicLibrary.process(), 9 | ); 10 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 7 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/dart_quickjs.dart: -------------------------------------------------------------------------------- 1 | library dart_quickjs; 2 | 3 | export 'src/bindings.dart'; 4 | export 'src/common.dart'; 5 | export 'src/extensions.dart'; 6 | export 'src/js_value.dart'; 7 | export 'src/library.dart'; 8 | export 'src/plugin.dart'; 9 | export 'src/runtime.dart'; 10 | export 'src/typedef.dart'; 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Classes/DartQuickjsPlugin.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | public class DartQuickjsPlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | } 7 | 8 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/Classes/SwiftDartQuickjsPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class SwiftDartQuickjsPlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | } 7 | 8 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import dart_quickjs 9 | import path_provider_foundation 10 | 11 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 12 | DartQuickjsPlugin.register(with: registry.registrar(forPlugin: "DartQuickjsPlugin")) 13 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 14 | } 15 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | 3 | include("${CMAKE_CURRENT_SOURCE_DIR}/../cxx/CMakeLists.txt") 4 | 5 | add_library( 6 | "quickjs" 7 | SHARED 8 | ${LIB_DIR}/ffi.cpp 9 | ) 10 | 11 | find_library( # Sets the name of the path variable. 12 | log-lib 13 | 14 | # Specifies the name of the NDK library that 15 | # you want CMake to locate. 16 | log ) 17 | 18 | target_link_libraries( 19 | quickjs 20 | quickjs_lib 21 | ${log-lib} 22 | ) 23 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cxx/quickjs/unicode_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | url="ftp://ftp.unicode.org/Public/13.0.0/ucd" 5 | emoji_url="${url}/emoji/emoji-data.txt" 6 | 7 | files="CaseFolding.txt DerivedNormalizationProps.txt PropList.txt \ 8 | SpecialCasing.txt CompositionExclusions.txt ScriptExtensions.txt \ 9 | UnicodeData.txt DerivedCoreProperties.txt NormalizationTest.txt Scripts.txt \ 10 | PropertyValueAliases.txt" 11 | 12 | mkdir -p unicode 13 | 14 | #for f in $files; do 15 | # g="${url}/${f}" 16 | # wget $g -O unicode/$f 17 | #done 18 | 19 | wget $emoji_url -O unicode/emoji-data.txt 20 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/ephemeral/ 38 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /cxx/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.7 FATAL_ERROR) 2 | set(LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) 3 | 4 | # quickjs 5 | set(QUICK_JS_LIB_DIR ${LIB_DIR}/quickjs) 6 | file (STRINGS "${QUICK_JS_LIB_DIR}/VERSION" QUICKJS_VERSION) 7 | add_library(quickjs_lib STATIC 8 | ${QUICK_JS_LIB_DIR}/cutils.c 9 | ${QUICK_JS_LIB_DIR}/libregexp.c 10 | ${QUICK_JS_LIB_DIR}/libunicode.c 11 | ${QUICK_JS_LIB_DIR}/quickjs.c 12 | ) 13 | 14 | project(quickjs_lib LANGUAGES C) 15 | target_compile_options(quickjs_lib PRIVATE "-DCONFIG_VERSION=\"${QUICKJS_VERSION}\"") 16 | target_compile_options(quickjs_lib PRIVATE "-DDUMP_LEAKS") 17 | -------------------------------------------------------------------------------- /cxx/prebuild.sh: -------------------------------------------------------------------------------- 1 | if [ -d "./cxx/" ];then 2 | rm -r ./cxx 3 | fi 4 | 5 | mkdir ./cxx 6 | 7 | sed 's/\#include \"quickjs\/quickjs.h\"/\#include \"quickjs.h\"/g' ../cxx/ffi.h > ./cxx/ffi.h 8 | sed 's/\#include \"quickjs\/quickjs.h\"/\#include \"quickjs.h\"/g' ../cxx/ffi.cpp > ./cxx/ffi.cpp 9 | 10 | cp ../cxx/quickjs/*.h ./cxx/ 11 | cp ../cxx/quickjs/cutils.c ./cxx/ 12 | cp ../cxx/quickjs/libregexp.c ./cxx/ 13 | cp ../cxx/quickjs/libunicode.c ./cxx/ 14 | 15 | quickjs_version=$(cat ../cxx/quickjs/VERSION) 16 | 17 | sed '1i\ 18 | \#define CONFIG_VERSION \"'$quickjs_version'\"\ 19 | \#define DUMP_LEAKS 1\ 20 | ' ../cxx/quickjs/quickjs.c > ./cxx/quickjs.c -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # dart_quickjs_example 2 | 3 | Demonstrates how to use the dart_quickjs plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /ios/Classes/DartQuickjsPlugin.m: -------------------------------------------------------------------------------- 1 | #import "DartQuickjsPlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "dart_quickjs-Swift.h" 9 | #endif 10 | 11 | @implementation DartQuickjsPlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftDartQuickjsPlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | .packages 30 | build/ 31 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.html": "html", 4 | "*.ast": "json", 5 | "*.txt": "makefile", 6 | "sstream": "cpp", 7 | "__config": "cpp", 8 | "__nullptr": "cpp", 9 | "__bit_reference": "cpp", 10 | "__node_handle": "cpp", 11 | "atomic": "cpp", 12 | "bitset": "cpp", 13 | "__memory": "cpp", 14 | "limits": "cpp", 15 | "locale": "cpp", 16 | "optional": "cpp", 17 | "ratio": "cpp", 18 | "system_error": "cpp", 19 | "tuple": "cpp", 20 | "type_traits": "cpp", 21 | "vector": "cpp", 22 | "chrono": "cpp", 23 | "cstddef": "cpp" 24 | }, 25 | "C_Cpp.errorSquiggles": "disabled" 26 | } -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = dart_quickjs_example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.allan.dartQuickjsExample 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.allan. All rights reserved. 15 | -------------------------------------------------------------------------------- /lib/src/cache.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | 3 | import 'library.dart'; 4 | import 'runtime.dart'; 5 | import 'typedef.dart'; 6 | 7 | class Cache { 8 | Cache._(); 9 | 10 | static final instance = Cache._(); 11 | 12 | final Map _runtimes = {}; 13 | 14 | // 获取运行时 15 | Runtime getRuntime(Pointer context) { 16 | final pointer = library.getRuntime(context); 17 | return _runtimes[pointer.hashCode]!; 18 | } 19 | 20 | // 保存运行时 21 | void saveRuntime(Pointer key, Runtime runtime) { 22 | _runtimes[key.hashCode] = runtime; 23 | } 24 | 25 | // 移除运行时 26 | void removeRuntime(Pointer key) { 27 | _runtimes.remove(key.hashCode); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /cxx/quickjs/tests/test_worker_module.js: -------------------------------------------------------------------------------- 1 | /* Worker code for test_worker.js */ 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | var parent = os.Worker.parent; 6 | 7 | function handle_msg(e) { 8 | var ev = e.data; 9 | // print("child_recv", JSON.stringify(ev)); 10 | switch(ev.type) { 11 | case "abort": 12 | parent.postMessage({ type: "done" }); 13 | break; 14 | case "sab": 15 | /* modify the SharedArrayBuffer */ 16 | ev.buf[2] = 10; 17 | parent.postMessage({ type: "sab_done", buf: ev.buf }); 18 | break; 19 | } 20 | } 21 | 22 | function worker_main() { 23 | var i; 24 | 25 | parent.onmessage = handle_msg; 26 | for(i = 0; i < 10; i++) { 27 | parent.postMessage({ type: "num", num: i }); 28 | } 29 | } 30 | 31 | worker_main(); 32 | -------------------------------------------------------------------------------- /lib/src/observer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | import 'js_value.dart'; 4 | 5 | class Observer { 6 | final Map _listeners = {}; 7 | 8 | // 订阅 9 | void on(String symbol, Function handle) { 10 | _listeners[symbol] = handle; 11 | } 12 | 13 | // 发布 14 | JSObject emit(String symbol, [List? args]) { 15 | if (_listeners.containsKey(symbol)) { 16 | final handle = _listeners[symbol]!; 17 | return Function.apply(handle, args ?? []) ?? JSUndefined(); 18 | } 19 | 20 | debugPrint('未找到$symbol处理方法, $args'); 21 | 22 | return JSUndefined(); 23 | } 24 | 25 | // 取消订阅 26 | void off(String symbol) { 27 | if (_listeners.containsKey(symbol)) { 28 | _listeners.remove(symbol); 29 | } 30 | } 31 | 32 | // 清除所有订阅 33 | void clear() { 34 | _listeners.clear(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | * TODO: Initial open source version 3 | ## 0.0.2 4 | * TODO: Fix that cannot be called under ios 5 | ## 0.0.3 6 | * TODO: Add a memory limit setting 7 | * TODO: Add an update stack top 8 | * TODO: Add a destroy method 9 | * TODO: Add a println print method 10 | * TODO: Optimize memory leaks 11 | ## 0.0.4 12 | * TODO: Addition of macOS platform, 13 | * TODO: addition of bytecode compilation 14 | * TODO: Addition of bytecode execution. 15 | ## 0.0.5 16 | * TODO: JSString adds `length` `indexOf` `lastIndexOf` `includes` `split` `concat` 17 | * TODO: JSArray adds `isArray` `join` `slice` `includes` 18 | * TODO: JSFunction adds the `off` method to remove subscriptions. 19 | * TODO: Update the JSFunction subscription logic to fix the issue where callback functions cannot be called when passed from Dart to JavaScript. 20 | * TODO: Add a new `JSRegExp` object. 21 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/allan/dart_quickjs/DartQuickjsPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.allan.dart_quickjs 2 | 3 | import androidx.annotation.NonNull 4 | 5 | import io.flutter.embedding.engine.plugins.FlutterPlugin 6 | import io.flutter.plugin.common.MethodCall 7 | import io.flutter.plugin.common.MethodChannel 8 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler 9 | import io.flutter.plugin.common.MethodChannel.Result 10 | 11 | /** DartQuickjsPlugin */ 12 | class DartQuickjsPlugin: FlutterPlugin, MethodCallHandler { 13 | private lateinit var channel : MethodChannel 14 | 15 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { 16 | } 17 | 18 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { 19 | } 20 | 21 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/test_point.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | import { Point } from "./point.so"; 3 | 4 | function assert(b, str) 5 | { 6 | if (b) { 7 | return; 8 | } else { 9 | throw Error("assertion failed: " + str); 10 | } 11 | } 12 | 13 | class ColorPoint extends Point { 14 | constructor(x, y, color) { 15 | super(x, y); 16 | this.color = color; 17 | } 18 | get_color() { 19 | return this.color; 20 | } 21 | }; 22 | 23 | function main() 24 | { 25 | var pt, pt2; 26 | 27 | pt = new Point(2, 3); 28 | assert(pt.x === 2); 29 | assert(pt.y === 3); 30 | pt.x = 4; 31 | assert(pt.x === 4); 32 | assert(pt.norm() == 5); 33 | 34 | pt2 = new ColorPoint(2, 3, 0xffffff); 35 | assert(pt2.x === 2); 36 | assert(pt2.color === 0xffffff); 37 | assert(pt2.get_color() === 0xffffff); 38 | } 39 | 40 | main(); 41 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - dart_quickjs (0.0.1): 3 | - Flutter 4 | - Flutter (1.0.0) 5 | - path_provider_foundation (0.0.1): 6 | - Flutter 7 | - FlutterMacOS 8 | 9 | DEPENDENCIES: 10 | - dart_quickjs (from `.symlinks/plugins/dart_quickjs/ios`) 11 | - Flutter (from `Flutter`) 12 | - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) 13 | 14 | EXTERNAL SOURCES: 15 | dart_quickjs: 16 | :path: ".symlinks/plugins/dart_quickjs/ios" 17 | Flutter: 18 | :path: Flutter 19 | path_provider_foundation: 20 | :path: ".symlinks/plugins/path_provider_foundation/ios" 21 | 22 | SPEC CHECKSUMS: 23 | dart_quickjs: 1b7347be89bb24a41ab4b006e3f1877f914a91a4 24 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a 25 | path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 26 | 27 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c 28 | 29 | COCOAPODS: 1.11.3 30 | -------------------------------------------------------------------------------- /macos/dart_quickjs.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint dart_quickjs.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'dart_quickjs' 7 | s.version = '0.0.1' 8 | s.summary = 'A new Flutter plugin project.' 9 | s.description = <<-DESC 10 | A new Flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | 16 | s.source = { :path => '.' } 17 | s.source_files = ['Classes/**/*', 'cxx/*.{c,cpp}'] 18 | s.dependency 'FlutterMacOS' 19 | 20 | s.platform = :osx, '10.11' 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } 22 | s.prepare_command = 'sh ../cxx/prebuild.sh' 23 | s.swift_version = '5.0' 24 | end 25 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Android Studio will place build artifacts here 45 | /android/app/debug 46 | /android/app/profile 47 | /android/app/release 48 | -------------------------------------------------------------------------------- /ios/dart_quickjs.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint dart_quickjs.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'dart_quickjs' 7 | s.version = '0.0.1' 8 | s.summary = 'A new Flutter plugin project.' 9 | s.description = <<-DESC 10 | A new Flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = ['Classes/**/*', 'cxx/*.{c,cpp}'] 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '9.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 22 | s.prepare_command = 'sh ../cxx/prebuild.sh' 23 | s.swift_version = '5.0' 24 | end 25 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: 85684f9300908116a78138ea4c6036c35c9a1236 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 17 | base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 18 | - platform: macos 19 | create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 20 | base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /example/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - dart_quickjs (0.0.1): 3 | - FlutterMacOS 4 | - FlutterMacOS (1.0.0) 5 | - path_provider_foundation (0.0.1): 6 | - Flutter 7 | - FlutterMacOS 8 | 9 | DEPENDENCIES: 10 | - dart_quickjs (from `Flutter/ephemeral/.symlinks/plugins/dart_quickjs/macos`) 11 | - FlutterMacOS (from `Flutter/ephemeral`) 12 | - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) 13 | 14 | EXTERNAL SOURCES: 15 | dart_quickjs: 16 | :path: Flutter/ephemeral/.symlinks/plugins/dart_quickjs/macos 17 | FlutterMacOS: 18 | :path: Flutter/ephemeral 19 | path_provider_foundation: 20 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos 21 | 22 | SPEC CHECKSUMS: 23 | dart_quickjs: 4e9149a6f1182884610d44a5bae030322d35afec 24 | FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 25 | path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 26 | 27 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c 28 | 29 | COCOAPODS: 1.11.3 30 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 allan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /cxx/quickjs/LICENSE: -------------------------------------------------------------------------------- 1 | QuickJS Javascript Engine 2 | 3 | Copyright (c) 2017-2021 Fabrice Bellard 4 | Copyright (c) 2017-2021 Charlie Gordon 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.allan.dart_quickjs' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.6.10' 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:7.1.2' 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | rootProject.allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'kotlin-android' 26 | 27 | android { 28 | compileSdkVersion 31 29 | 30 | compileOptions { 31 | sourceCompatibility JavaVersion.VERSION_1_8 32 | targetCompatibility JavaVersion.VERSION_1_8 33 | } 34 | 35 | kotlinOptions { 36 | jvmTarget = '1.8' 37 | } 38 | 39 | sourceSets { 40 | main.java.srcDirs += 'src/main/kotlin' 41 | } 42 | 43 | defaultConfig { 44 | minSdkVersion 16 45 | } 46 | 47 | externalNativeBuild { 48 | cmake { 49 | path "CMakeLists.txt" 50 | } 51 | } 52 | } 53 | 54 | dependencies { 55 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 56 | } 57 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: 85684f9300908116a78138ea4c6036c35c9a1236 8 | channel: stable 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 17 | base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 18 | - platform: android 19 | create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 20 | base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 21 | - platform: ios 22 | create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 23 | base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 24 | - platform: macos 25 | create_revision: 85684f9300908116a78138ea4c6036c35c9a1236 26 | base_revision: 85684f9300908116a78138ea4c6036c35c9a1236 27 | 28 | # User provided section 29 | 30 | # List of Local paths (relative to this file) that should be 31 | # ignored by the migrate tool. 32 | # 33 | # Files that are not part of the templates will be ignored by default. 34 | unmanaged_files: 35 | - 'lib/main.dart' 36 | - 'ios/Runner.xcodeproj/project.pbxproj' 37 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/src/common.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | import 'package:ffi/ffi.dart'; 3 | 4 | import 'js_value.dart'; 5 | import 'library.dart'; 6 | import 'typedef.dart'; 7 | import 'extensions.dart'; 8 | 9 | class Common { 10 | Common._(); 11 | 12 | // js to string 13 | static String? jsToString( 14 | Pointer context, Pointer value) { 15 | final pointer = library.jsToCString(context, value); 16 | 17 | if (pointer.address != 0) { 18 | final message = pointer.cast().toDartString(); 19 | library.freeCString(context, pointer); 20 | return message; 21 | } 22 | 23 | return null; 24 | } 25 | 26 | // 转换参数 27 | static Pointer formatArgs(List args) { 28 | final size = args.length * jsValueSizeOf; 29 | final data = calloc(size).cast(); 30 | 31 | for (int index = 0; index < args.length; index++) { 32 | library.setValueAt(data, index, args[index].pointer); 33 | } 34 | 35 | return data; 36 | } 37 | 38 | // 执行构造函数 39 | static Pointer callConstructor( 40 | Pointer context, 41 | Pointer constructor, [ 42 | List? args, 43 | ]) { 44 | if (library.isConstructor(context, constructor) == 0) { 45 | throw 'constructor不是构造函数'; 46 | } 47 | 48 | final pointer = library.callConstructor( 49 | context, 50 | constructor, 51 | args?.length ?? 0, 52 | args == null ? undefined : Common.formatArgs(args), 53 | ); 54 | 55 | if (pointer.isException) { 56 | final message = context.exception; 57 | throw '函数调用执行异常:$message'; 58 | } 59 | 60 | return pointer; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Dart Quickjs 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | dart_quickjs_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /cxx/quickjs/tests/test_worker.js: -------------------------------------------------------------------------------- 1 | /* os.Worker API test */ 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | function assert(actual, expected, message) { 6 | if (arguments.length == 1) 7 | expected = true; 8 | 9 | if (actual === expected) 10 | return; 11 | 12 | if (actual !== null && expected !== null 13 | && typeof actual == 'object' && typeof expected == 'object' 14 | && actual.toString() === expected.toString()) 15 | return; 16 | 17 | throw Error("assertion failed: got |" + actual + "|" + 18 | ", expected |" + expected + "|" + 19 | (message ? " (" + message + ")" : "")); 20 | } 21 | 22 | var worker; 23 | 24 | function test_worker() 25 | { 26 | var counter; 27 | 28 | worker = new os.Worker("./test_worker_module.js"); 29 | 30 | counter = 0; 31 | worker.onmessage = function (e) { 32 | var ev = e.data; 33 | // print("recv", JSON.stringify(ev)); 34 | switch(ev.type) { 35 | case "num": 36 | assert(ev.num, counter); 37 | counter++; 38 | if (counter == 10) { 39 | /* test SharedArrayBuffer modification */ 40 | let sab = new SharedArrayBuffer(10); 41 | let buf = new Uint8Array(sab); 42 | worker.postMessage({ type: "sab", buf: buf }); 43 | } 44 | break; 45 | case "sab_done": 46 | { 47 | let buf = ev.buf; 48 | /* check that the SharedArrayBuffer was modified */ 49 | assert(buf[2], 10); 50 | worker.postMessage({ type: "abort" }); 51 | } 52 | break; 53 | case "done": 54 | /* terminate */ 55 | worker.onmessage = null; 56 | break; 57 | } 58 | }; 59 | } 60 | 61 | 62 | test_worker(); 63 | -------------------------------------------------------------------------------- /lib/src/extensions.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:ffi'; 3 | 4 | import 'library.dart'; 5 | import 'js_value.dart'; 6 | import 'common.dart'; 7 | import 'typedef.dart'; 8 | 9 | extension PointerJSValue on Pointer { 10 | // 是否异常 11 | bool get isException { 12 | return ref.tag == 6; 13 | } 14 | 15 | // 转换成js object 16 | JSObject toJSValue(Pointer context) { 17 | switch (ref.tag) { 18 | case JSValueTag.string: 19 | return JSString(context, this); 20 | case JSValueTag.number: 21 | return JSNumber(context, this); 22 | case JSValueTag.float64: 23 | return JSFloat(context, this); 24 | case JSValueTag.bool: 25 | return JSBool(context, this); 26 | case JSValueTag.nullptr: 27 | return JSNull(); 28 | case JSValueTag.undefined: 29 | return JSUndefined(); 30 | } 31 | 32 | if (library.isArray(context, this) == 1) { 33 | return JSArray(context, this); 34 | } else if (library.isFunction(context, this) == 1) { 35 | return JSFunction(context, this); 36 | } else if (library.isPromise(context, this) == 1) { 37 | return JSPromise(context, this); 38 | } 39 | 40 | return JSObject(context, this); 41 | } 42 | } 43 | 44 | extension PointerJSContext on Pointer { 45 | // 获取异常 46 | String? get exception { 47 | final value = library.getException(this); 48 | 49 | if (value.ref.tag != JSValueTag.nullptr) { 50 | return Common.jsToString(this, value); 51 | } 52 | 53 | return null; 54 | } 55 | 56 | // 执行挂起的任务 57 | void executePendingJob() { 58 | final runtime = library.getRuntime(this); 59 | 60 | Future(() { 61 | while (true) { 62 | int err = library.executePendingJob(runtime); 63 | 64 | if (err <= 0) { 65 | if (err < 0) { 66 | throw exception ?? 'Dispatch Error'; 67 | } 68 | 69 | break; 70 | } 71 | } 72 | }); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:dart_quickjs/dart_quickjs.dart'; 3 | 4 | void main(List args) { 5 | runApp(const App()); 6 | } 7 | 8 | class Test extends Plugin { 9 | late Runtime _runtime; 10 | 11 | @override 12 | void onCreate(Runtime runtime) { 13 | _runtime = runtime; 14 | runtime.global.setPropertyStr( 15 | 'getMessage', 16 | JSFunction.create(runtime.context, test), 17 | ); 18 | } 19 | 20 | JSString test(JSString data) { 21 | return JSString.create(_runtime.context, '${data.value} World'); 22 | } 23 | 24 | @override 25 | void destroy(Runtime runtime) {} 26 | } 27 | 28 | class App extends StatelessWidget { 29 | const App({Key? key}) : super(key: key); 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return MaterialApp( 34 | home: Home(), 35 | ); 36 | } 37 | } 38 | 39 | class Home extends StatelessWidget { 40 | Home({Key? key}) : super(key: key); 41 | 42 | final runtime = Runtime( 43 | plugins: [ 44 | Test(), 45 | ], 46 | ); 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | return Scaffold( 51 | body: Center( 52 | child: Column( 53 | mainAxisAlignment: MainAxisAlignment.center, 54 | children: [ 55 | // 执行字符串 56 | ElevatedButton( 57 | onPressed: () async { 58 | final reg = JSRegExp.create(runtime.context, 'Hello'); 59 | final value = reg.exec('Hello World'); 60 | print(value); 61 | }, 62 | child: const Text('Run Script'), 63 | ), 64 | const SizedBox(height: 20), 65 | // 销毁 66 | ElevatedButton( 67 | onPressed: () async { 68 | runtime.destroy(); 69 | }, 70 | child: const Text('Destroy'), 71 | ), 72 | ], 73 | ), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/pi_bigfloat.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the QuickJS bigfloat type 3 | * (binary floating point) 4 | */ 5 | "use strict"; 6 | 7 | /* compute PI with a precision of 'prec' bits */ 8 | function calc_pi() { 9 | const CHUD_A = 13591409n; 10 | const CHUD_B = 545140134n; 11 | const CHUD_C = 640320n; 12 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */ 13 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ 14 | 15 | /* return [P, Q, G] */ 16 | function chud_bs(a, b, need_G) { 17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; 18 | if (a == (b - 1n)) { 19 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); 20 | P = BigFloat(G * (CHUD_B * b + CHUD_A)); 21 | if (b & 1n) 22 | P = -P; 23 | G = BigFloat(G); 24 | Q = BigFloat(b * b * b * CHUD_C3); 25 | } else { 26 | c = (a + b) >> 1n; 27 | [P1, Q1, G1] = chud_bs(a, c, true); 28 | [P2, Q2, G2] = chud_bs(c, b, need_G); 29 | P = P1 * Q2 + P2 * G1; 30 | Q = Q1 * Q2; 31 | if (need_G) 32 | G = G1 * G2; 33 | else 34 | G = 0l; 35 | } 36 | return [P, Q, G]; 37 | } 38 | 39 | var n, P, Q, G; 40 | /* number of serie terms */ 41 | n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n; 42 | [P, Q, G] = chud_bs(0n, n, false); 43 | Q = Q / (P + Q * BigFloat(CHUD_A)); 44 | G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(CHUD_C)); 45 | return Q * G; 46 | } 47 | 48 | (function() { 49 | var r, n_digits, n_bits; 50 | if (typeof scriptArgs != "undefined") { 51 | if (scriptArgs.length < 2) { 52 | print("usage: pi n_digits"); 53 | return; 54 | } 55 | n_digits = scriptArgs[1]; 56 | } else { 57 | n_digits = 1000; 58 | } 59 | n_bits = Math.ceil(n_digits * Math.log2(10)); 60 | /* we add more bits to reduce the probability of bad rounding for 61 | the last digits */ 62 | BigFloatEnv.setPrec( () => { 63 | r = calc_pi(); 64 | print(r.toFixed(n_digits, BigFloatEnv.RNDZ)); 65 | }, n_bits + 32); 66 | })(); 67 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/pi_bigdecimal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the QuickJS bigdecimal type 3 | * (decimal floating point) 4 | */ 5 | "use strict"; 6 | 7 | /* compute PI with a precision of 'prec' digits */ 8 | function calc_pi(prec) { 9 | const CHUD_A = 13591409m; 10 | const CHUD_B = 545140134m; 11 | const CHUD_C = 640320m; 12 | const CHUD_C3 = 10939058860032000m; /* C^3/24 */ 13 | const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(C/12)*3 */ 14 | 15 | /* return [P, Q, G] */ 16 | function chud_bs(a, b, need_G) { 17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2, b1; 18 | if (a == (b - 1n)) { 19 | b1 = BigDecimal(b); 20 | G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m); 21 | P = G * (CHUD_B * b1 + CHUD_A); 22 | if (b & 1n) 23 | P = -P; 24 | G = G; 25 | Q = b1 * b1 * b1 * CHUD_C3; 26 | } else { 27 | c = (a + b) >> 1n; 28 | [P1, Q1, G1] = chud_bs(a, c, true); 29 | [P2, Q2, G2] = chud_bs(c, b, need_G); 30 | P = P1 * Q2 + P2 * G1; 31 | Q = Q1 * Q2; 32 | if (need_G) 33 | G = G1 * G2; 34 | else 35 | G = 0m; 36 | } 37 | return [P, Q, G]; 38 | } 39 | 40 | var n, P, Q, G; 41 | /* number of serie terms */ 42 | n = BigInt(Math.ceil(prec / CHUD_DIGITS_PER_TERM)) + 10n; 43 | [P, Q, G] = chud_bs(0n, n, false); 44 | Q = BigDecimal.div(Q, (P + Q * CHUD_A), 45 | { roundingMode: "half-even", 46 | maximumSignificantDigits: prec }); 47 | G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C, 48 | { roundingMode: "half-even", 49 | maximumSignificantDigits: prec }); 50 | return Q * G; 51 | } 52 | 53 | (function() { 54 | var r, n_digits, n_bits; 55 | if (typeof scriptArgs != "undefined") { 56 | if (scriptArgs.length < 2) { 57 | print("usage: pi n_digits"); 58 | return; 59 | } 60 | n_digits = scriptArgs[1] | 0; 61 | } else { 62 | n_digits = 1000; 63 | } 64 | /* we add more digits to reduce the probability of bad rounding for 65 | the last digits */ 66 | r = calc_pi(n_digits + 20); 67 | print(r.toFixed(n_digits, "down")); 68 | })(); 69 | -------------------------------------------------------------------------------- /ios/cxx/libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char, 3) 29 | DEF(char32, 5) 30 | DEF(dot, 1) 31 | DEF(any, 1) /* same as dot but match any character including line terminator */ 32 | DEF(line_start, 1) 33 | DEF(line_end, 1) 34 | DEF(goto, 5) 35 | DEF(split_goto_first, 5) 36 | DEF(split_next_first, 5) 37 | DEF(match, 1) 38 | DEF(save_start, 2) /* save start position */ 39 | DEF(save_end, 2) /* save end position, must come after saved_start */ 40 | DEF(save_reset, 3) /* reset save positions */ 41 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 42 | DEF(push_i32, 5) /* push integer on the stack */ 43 | DEF(drop, 1) 44 | DEF(word_boundary, 1) 45 | DEF(not_word_boundary, 1) 46 | DEF(back_reference, 2) 47 | DEF(backward_back_reference, 2) /* must come after back_reference */ 48 | DEF(range, 3) /* variable length */ 49 | DEF(range32, 3) /* variable length */ 50 | DEF(lookahead, 5) 51 | DEF(negative_lookahead, 5) 52 | DEF(push_char_pos, 1) /* push the character position on the stack */ 53 | DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character 54 | position */ 55 | DEF(prev, 1) /* go to the previous char */ 56 | DEF(simple_greedy_quant, 17) 57 | 58 | #endif /* DEF */ 59 | -------------------------------------------------------------------------------- /cxx/quickjs/libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char, 3) 29 | DEF(char32, 5) 30 | DEF(dot, 1) 31 | DEF(any, 1) /* same as dot but match any character including line terminator */ 32 | DEF(line_start, 1) 33 | DEF(line_end, 1) 34 | DEF(goto, 5) 35 | DEF(split_goto_first, 5) 36 | DEF(split_next_first, 5) 37 | DEF(match, 1) 38 | DEF(save_start, 2) /* save start position */ 39 | DEF(save_end, 2) /* save end position, must come after saved_start */ 40 | DEF(save_reset, 3) /* reset save positions */ 41 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 42 | DEF(push_i32, 5) /* push integer on the stack */ 43 | DEF(drop, 1) 44 | DEF(word_boundary, 1) 45 | DEF(not_word_boundary, 1) 46 | DEF(back_reference, 2) 47 | DEF(backward_back_reference, 2) /* must come after back_reference */ 48 | DEF(range, 3) /* variable length */ 49 | DEF(range32, 3) /* variable length */ 50 | DEF(lookahead, 5) 51 | DEF(negative_lookahead, 5) 52 | DEF(push_char_pos, 1) /* push the character position on the stack */ 53 | DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character 54 | position */ 55 | DEF(prev, 1) /* go to the previous char */ 56 | DEF(simple_greedy_quant, 17) 57 | 58 | #endif /* DEF */ 59 | -------------------------------------------------------------------------------- /macos/cxx/libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char, 3) 29 | DEF(char32, 5) 30 | DEF(dot, 1) 31 | DEF(any, 1) /* same as dot but match any character including line terminator */ 32 | DEF(line_start, 1) 33 | DEF(line_end, 1) 34 | DEF(goto, 5) 35 | DEF(split_goto_first, 5) 36 | DEF(split_next_first, 5) 37 | DEF(match, 1) 38 | DEF(save_start, 2) /* save start position */ 39 | DEF(save_end, 2) /* save end position, must come after saved_start */ 40 | DEF(save_reset, 3) /* reset save positions */ 41 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 42 | DEF(push_i32, 5) /* push integer on the stack */ 43 | DEF(drop, 1) 44 | DEF(word_boundary, 1) 45 | DEF(not_word_boundary, 1) 46 | DEF(back_reference, 2) 47 | DEF(backward_back_reference, 2) /* must come after back_reference */ 48 | DEF(range, 3) /* variable length */ 49 | DEF(range32, 3) /* variable length */ 50 | DEF(lookahead, 5) 51 | DEF(negative_lookahead, 5) 52 | DEF(push_char_pos, 1) /* push the character position on the stack */ 53 | DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character 54 | position */ 55 | DEF(prev, 1) /* go to the previous char */ 56 | DEF(simple_greedy_quant, 17) 57 | 58 | #endif /* DEF */ 59 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.allan.dart_quickjs_example" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 50 | minSdkVersion flutter.minSdkVersion 51 | targetSdkVersion flutter.targetSdkVersion 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | buildTypes { 57 | release { 58 | // TODO: Add your own signing config for the release build. 59 | // Signing with the debug keys for now, so `flutter run --release` works. 60 | signingConfig signingConfigs.debug 61 | } 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | -------------------------------------------------------------------------------- /cxx/quickjs/tests/test262.patch: -------------------------------------------------------------------------------- 1 | diff --git a/harness/atomicsHelper.js b/harness/atomicsHelper.js 2 | index 9c1217351e..3c24755558 100644 3 | --- a/harness/atomicsHelper.js 4 | +++ b/harness/atomicsHelper.js 5 | @@ -227,10 +227,14 @@ $262.agent.waitUntil = function(typedArray, index, expected) { 6 | * } 7 | */ 8 | $262.agent.timeouts = { 9 | - yield: 100, 10 | - small: 200, 11 | - long: 1000, 12 | - huge: 10000, 13 | +// yield: 100, 14 | +// small: 200, 15 | +// long: 1000, 16 | +// huge: 10000, 17 | + yield: 20, 18 | + small: 20, 19 | + long: 100, 20 | + huge: 1000, 21 | }; 22 | 23 | /** 24 | diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js 25 | index be7039fda0..7b38abf8df 100644 26 | --- a/harness/regExpUtils.js 27 | +++ b/harness/regExpUtils.js 28 | @@ -6,24 +6,27 @@ description: | 29 | defines: [buildString, testPropertyEscapes, matchValidator] 30 | ---*/ 31 | 32 | +if ($262 && typeof $262.codePointRange === "function") { 33 | + /* use C function to build the codePointRange (much faster with 34 | + slow JS engines) */ 35 | + codePointRange = $262.codePointRange; 36 | +} else { 37 | + codePointRange = function codePointRange(start, end) { 38 | + const codePoints = []; 39 | + let length = 0; 40 | + for (codePoint = start; codePoint < end; codePoint++) { 41 | + codePoints[length++] = codePoint; 42 | + } 43 | + return String.fromCodePoint.apply(null, codePoints); 44 | + } 45 | +} 46 | + 47 | function buildString({ loneCodePoints, ranges }) { 48 | - const CHUNK_SIZE = 10000; 49 | - let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); 50 | - for (let i = 0; i < ranges.length; i++) { 51 | - const range = ranges[i]; 52 | - const start = range[0]; 53 | - const end = range[1]; 54 | - const codePoints = []; 55 | - for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { 56 | - codePoints[length++] = codePoint; 57 | - if (length === CHUNK_SIZE) { 58 | - result += Reflect.apply(String.fromCodePoint, null, codePoints); 59 | - codePoints.length = length = 0; 60 | - } 61 | + let result = String.fromCodePoint.apply(null, loneCodePoints); 62 | + for (const [start, end] of ranges) { 63 | + result += codePointRange(start, end + 1); 64 | } 65 | - result += Reflect.apply(String.fromCodePoint, null, codePoints); 66 | - } 67 | - return result; 68 | + return result; 69 | } 70 | 71 | function testPropertyEscapes(regex, string, expression) { 72 | -------------------------------------------------------------------------------- /lib/src/typedef.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi'; 2 | 3 | // 运行时 4 | class JSRuntime extends Opaque {} 5 | 6 | // 上下文 7 | class JSContext extends Opaque {} 8 | 9 | // 通道回调 10 | typedef ChannelCallback = Pointer Function( 11 | Pointer, 12 | Pointer, 13 | Int32, 14 | Pointer, 15 | ); 16 | 17 | // 通道方法 18 | typedef Channel = NativeFunction; 19 | 20 | // 模块加载 21 | typedef ModuleLoader = String Function(String name); 22 | 23 | // js对象 24 | class JSValue extends Struct { 25 | external JSValueUnion u; 26 | 27 | @Int64() 28 | external int tag; 29 | } 30 | 31 | class JSValueUnion extends Union { 32 | @Int32() 33 | external int int32; 34 | 35 | @Double() 36 | external double float64; 37 | 38 | external Pointer ptr; 39 | } 40 | 41 | // js类型标签 42 | class JSValueTag { 43 | static const first = -11; 44 | 45 | static const decimal = -11; 46 | 47 | static const bigInt = -10; 48 | 49 | static const bigFloat = -9; 50 | 51 | static const symbol = -8; 52 | 53 | static const string = -7; 54 | 55 | static const module = -3; 56 | 57 | static const bytecode = -2; 58 | 59 | static const object = -1; 60 | 61 | static const number = 0; 62 | 63 | static const bool = 1; 64 | 65 | static const nullptr = 2; 66 | 67 | static const undefined = 3; 68 | 69 | static const uninitialized = 4; 70 | 71 | static const catchOffset = 5; 72 | 73 | static const exception = 6; 74 | 75 | static const float64 = 7; 76 | } 77 | 78 | enum JSEvalType { 79 | global(0), 80 | 81 | module(1), 82 | 83 | direct(2), 84 | 85 | indirect(3), 86 | 87 | mask(3); 88 | 89 | const JSEvalType(this.value); 90 | 91 | final int value; 92 | } 93 | 94 | // 属性flags 95 | enum JSProp { 96 | configurable(1), 97 | 98 | writable(2), 99 | 100 | enumerable(4), 101 | 102 | cwe(7), 103 | 104 | length(8), 105 | 106 | tmask(48), 107 | 108 | normal(0), 109 | 110 | getset(16), 111 | 112 | varref(32), 113 | 114 | autoinit(48), 115 | 116 | hasShift(8), 117 | 118 | hasConfigurable(256), 119 | 120 | hasWritable(512), 121 | 122 | hasEnumerable(1024), 123 | 124 | hasGet(2048), 125 | 126 | hasSet(4096), 127 | 128 | hasValue(8192), 129 | 130 | cast(16384), 131 | 132 | throwStrict(32768), 133 | 134 | noAdd(65536), 135 | 136 | noExotic(131072); 137 | 138 | const JSProp(this.value); 139 | 140 | final int value; 141 | } 142 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/fib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | 26 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 27 | 28 | static int fib(int n) 29 | { 30 | if (n <= 0) 31 | return 0; 32 | else if (n == 1) 33 | return 1; 34 | else 35 | return fib(n - 1) + fib(n - 2); 36 | } 37 | 38 | static JSValue js_fib(JSContext *ctx, JSValueConst this_val, 39 | int argc, JSValueConst *argv) 40 | { 41 | int n, res; 42 | if (JS_ToInt32(ctx, &n, argv[0])) 43 | return JS_EXCEPTION; 44 | res = fib(n); 45 | return JS_NewInt32(ctx, res); 46 | } 47 | 48 | static const JSCFunctionListEntry js_fib_funcs[] = { 49 | JS_CFUNC_DEF("fib", 1, js_fib ), 50 | }; 51 | 52 | static int js_fib_init(JSContext *ctx, JSModuleDef *m) 53 | { 54 | return JS_SetModuleExportList(ctx, m, js_fib_funcs, 55 | countof(js_fib_funcs)); 56 | } 57 | 58 | #ifdef JS_SHARED_LIBRARY 59 | #define JS_INIT_MODULE js_init_module 60 | #else 61 | #define JS_INIT_MODULE js_init_module_fib 62 | #endif 63 | 64 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) 65 | { 66 | JSModuleDef *m; 67 | m = JS_NewCModule(ctx, module_name, js_fib_init); 68 | if (!m) 69 | return NULL; 70 | JS_AddModuleExportList(ctx, m, js_fib_funcs, countof(js_fib_funcs)); 71 | return m; 72 | } 73 | -------------------------------------------------------------------------------- /ios/cxx/quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 39 | void js_std_loop(JSContext *ctx); 40 | void js_std_init_handlers(JSRuntime *rt); 41 | void js_std_free_handlers(JSRuntime *rt); 42 | void js_std_dump_error(JSContext *ctx); 43 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 44 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 45 | JS_BOOL use_realpath, JS_BOOL is_main); 46 | JSModuleDef *js_module_loader(JSContext *ctx, 47 | const char *module_name, void *opaque); 48 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 49 | int flags); 50 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 51 | JSValueConst reason, 52 | JS_BOOL is_handled, void *opaque); 53 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 54 | 55 | #ifdef __cplusplus 56 | } /* extern "C" { */ 57 | #endif 58 | 59 | #endif /* QUICKJS_LIBC_H */ 60 | -------------------------------------------------------------------------------- /cxx/quickjs/quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 39 | void js_std_loop(JSContext *ctx); 40 | void js_std_init_handlers(JSRuntime *rt); 41 | void js_std_free_handlers(JSRuntime *rt); 42 | void js_std_dump_error(JSContext *ctx); 43 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 44 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 45 | JS_BOOL use_realpath, JS_BOOL is_main); 46 | JSModuleDef *js_module_loader(JSContext *ctx, 47 | const char *module_name, void *opaque); 48 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 49 | int flags); 50 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 51 | JSValueConst reason, 52 | JS_BOOL is_handled, void *opaque); 53 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 54 | 55 | #ifdef __cplusplus 56 | } /* extern "C" { */ 57 | #endif 58 | 59 | #endif /* QUICKJS_LIBC_H */ 60 | -------------------------------------------------------------------------------- /macos/cxx/quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 39 | void js_std_loop(JSContext *ctx); 40 | void js_std_init_handlers(JSRuntime *rt); 41 | void js_std_free_handlers(JSRuntime *rt); 42 | void js_std_dump_error(JSContext *ctx); 43 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 44 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 45 | JS_BOOL use_realpath, JS_BOOL is_main); 46 | JSModuleDef *js_module_loader(JSContext *ctx, 47 | const char *module_name, void *opaque); 48 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 49 | int flags); 50 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 51 | JSValueConst reason, 52 | JS_BOOL is_handled, void *opaque); 53 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 54 | 55 | #ifdef __cplusplus 56 | } /* extern "C" { */ 57 | #endif 58 | 59 | #endif /* QUICKJS_LIBC_H */ 60 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_quickjs 2 | description: dart_quickjs is a binding for the QuickJS engine using Dart, which supports executing JavaScript code on Android and iOS 3 | version: 0.0.6 4 | homepage: https://github.com/allan-hx/dart_quickjs 5 | repository: https://github.com/allan-hx/dart_quickjs 6 | 7 | environment: 8 | sdk: ">=2.17.5 <3.0.0" 9 | flutter: ">=2.5.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | ffi: ^2.0.1 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | flutter_lints: ^2.0.0 20 | 21 | # For information on the generic Dart part of this file, see the 22 | # following page: https://dart.dev/tools/pub/pubspec 23 | 24 | # The following section is specific to Flutter packages. 25 | flutter: 26 | # This section identifies this Flutter project as a plugin project. 27 | # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) 28 | # which should be registered in the plugin registry. This is required for 29 | # using method channels. 30 | # The Android 'package' specifies package in which the registered class is. 31 | # This is required for using method channels on Android. 32 | # The 'ffiPlugin' specifies that native code should be built and bundled. 33 | # This is required for using `dart:ffi`. 34 | # All these are used by the tooling to maintain consistency when 35 | # adding or updating assets for this project. 36 | plugin: 37 | platforms: 38 | android: 39 | package: com.allan.dart_quickjs 40 | pluginClass: DartQuickjsPlugin 41 | ios: 42 | pluginClass: DartQuickjsPlugin 43 | macos: 44 | pluginClass: DartQuickjsPlugin 45 | 46 | # To add assets to your plugin package, add an assets section, like this: 47 | # assets: 48 | # - images/a_dot_burr.jpeg 49 | # - images/a_dot_ham.jpeg 50 | # 51 | # For details regarding assets in packages, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | # 54 | # An image asset can refer to one or more resolution-specific "variants", see 55 | # https://flutter.dev/assets-and-images/#resolution-aware 56 | 57 | # To add custom fonts to your plugin package, add a fonts section here, 58 | # in this "flutter" section. Each entry in this list should have a 59 | # "family" key with the font family name, and a "fonts" key with a 60 | # list giving the asset and other descriptors for the font. For 61 | # example: 62 | # fonts: 63 | # - family: Schyler 64 | # fonts: 65 | # - asset: fonts/Schyler-Regular.ttf 66 | # - asset: fonts/Schyler-Italic.ttf 67 | # style: italic 68 | # - family: Trajan Pro 69 | # fonts: 70 | # - asset: fonts/TrajanPro.ttf 71 | # - asset: fonts/TrajanPro_Bold.ttf 72 | # weight: 700 73 | # 74 | # For details regarding fonts in packages, see 75 | # https://flutter.dev/custom-fonts/#from-packages 76 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /cxx/quickjs/TODO: -------------------------------------------------------------------------------- 1 | Bugs: 2 | - modules: better error handling with cyclic module references 3 | 4 | Misc ideas: 5 | - use custom printf to avoid compatibility issues with floating point numbers 6 | - consistent naming for preprocessor defines 7 | - unify coding style and naming conventions 8 | - use names from the ECMA spec in library implementation 9 | - use byte code emitters with typed arguments (for clarity) 10 | - use 2 bytecode DynBufs in JSFunctionDef, one for reading, one for writing 11 | and use the same wrappers in all phases 12 | - use more generic method for line numbers in resolve_variables and resolve_labels 13 | - use custom timezone support to avoid C library compatibility issues 14 | 15 | Memory: 16 | - use memory pools for objects, etc? 17 | - test border cases for max number of atoms, object properties, string length 18 | - add emergency malloc mode for out of memory exceptions. 19 | - test all DynBuf memory errors 20 | - test all js_realloc memory errors 21 | - improve JS_ComputeMemoryUsage() with more info 22 | 23 | Built-in standard library: 24 | - BSD sockets 25 | - modules: use realpath in module name normalizer and put it in quickjs-libc 26 | - modules: if no ".", use a well known module loading path ? 27 | - get rid of __loadScript, use more common name 28 | 29 | REPL: 30 | - debugger 31 | - readline: support MS Windows terminal 32 | - readline: handle dynamic terminal resizing 33 | - readline: handle double width unicode characters 34 | - multiline editing 35 | - runtime object and function inspectors 36 | - interactive object browser 37 | - use more generic approach to display evaluation results 38 | - improve directive handling: dispatch, colorize, completion... 39 | - save history 40 | - close all predefined methods in repl.js and jscalc.js 41 | 42 | Optimization ideas: 43 | - 64-bit atoms in 64-bit mode ? 44 | - 64-bit small bigint in 64-bit mode ? 45 | - reuse stack slots for disjoint scopes, if strip 46 | - add heuristic to avoid some cycles in closures 47 | - small String (0-2 charcodes) with immediate storage 48 | - perform static string concatenation at compile time 49 | - optimize string concatenation with ropes or miniropes? 50 | - add implicit numeric strings for Uint32 numbers? 51 | - optimize `s += a + b`, `s += a.b` and similar simple expressions 52 | - ensure string canonical representation and optimise comparisons and hashes? 53 | - remove JSObject.first_weak_ref, use bit+context based hashed array for weak references 54 | - property access optimization on the global object, functions, 55 | prototypes and special non extensible objects. 56 | - create object literals with the correct length by backpatching length argument 57 | - remove redundant set_loc_uninitialized/check_uninitialized opcodes 58 | - peephole optim: push_atom_value, to_propkey -> push_atom_value 59 | - peephole optim: put_loc x, get_loc_check x -> set_loc x 60 | - convert slow array to fast array when all properties != length are numeric 61 | - optimize destructuring assignments for global and local variables 62 | - implement some form of tail-call-optimization 63 | - optimize OP_apply 64 | - optimize f(...b) 65 | 66 | Test262o: 0/11262 errors, 463 excluded 67 | Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch) 68 | 69 | Result: 35/75280 errors, 909 excluded, 585 skipped 70 | Test262 commit: 31126581e7290f9233c29cefd93f66c6ac78f1c9 71 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dart_quickjs_example 2 | description: Demonstrates how to use the dart_quickjs plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | environment: 9 | sdk: ">=2.17.5 <3.0.0" 10 | 11 | # Dependencies specify other packages that your package needs in order to work. 12 | # To automatically upgrade your package dependencies to the latest versions 13 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 14 | # dependencies can be manually updated by changing the version numbers below to 15 | # the latest version available on pub.dev. To see which dependencies have newer 16 | # versions available, run `flutter pub outdated`. 17 | dependencies: 18 | flutter: 19 | sdk: flutter 20 | path_provider: ^2.0.13 21 | dart_quickjs: 22 | path: ../ 23 | # dart_quickjs: ^0.0.4 24 | 25 | # The following adds the Cupertino Icons font to your application. 26 | # Use with the CupertinoIcons class for iOS style icons. 27 | cupertino_icons: ^1.0.2 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | # The "flutter_lints" package below contains a set of recommended lints to 34 | # encourage good coding practices. The lint set provided by the package is 35 | # activated in the `analysis_options.yaml` file located at the root of your 36 | # package. See that file for information about deactivating specific lint 37 | # rules and activating additional ones. 38 | flutter_lints: ^2.0.0 39 | 40 | # For information on the generic Dart part of this file, see the 41 | # following page: https://dart.dev/tools/pub/pubspec 42 | 43 | # The following section is specific to Flutter packages. 44 | flutter: 45 | 46 | # The following line ensures that the Material Icons font is 47 | # included with your application, so that you can use the icons in 48 | # the material Icons class. 49 | uses-material-design: true 50 | 51 | # To add assets to your application, add an assets section, like this: 52 | assets: 53 | - assets/ 54 | # - images/a_dot_burr.jpeg 55 | # - images/a_dot_ham.jpeg 56 | 57 | # An image asset can refer to one or more resolution-specific "variants", see 58 | # https://flutter.dev/assets-and-images/#resolution-aware 59 | 60 | # For details regarding adding assets from package dependencies, see 61 | # https://flutter.dev/assets-and-images/#from-packages 62 | 63 | # To add custom fonts to your application, add a fonts section here, 64 | # in this "flutter" section. Each entry in this list should have a 65 | # "family" key with the font family name, and a "fonts" key with a 66 | # list giving the asset and other descriptors for the font. For 67 | # example: 68 | # fonts: 69 | # - family: Schyler 70 | # fonts: 71 | # - asset: fonts/Schyler-Regular.ttf 72 | # - asset: fonts/Schyler-Italic.ttf 73 | # style: italic 74 | # - family: Trajan Pro 75 | # fonts: 76 | # - asset: fonts/TrajanPro.ttf 77 | # - asset: fonts/TrajanPro_Bold.ttf 78 | # weight: 700 79 | # 80 | # For details regarding fonts from package dependencies, 81 | # see https://flutter.dev/custom-fonts/#from-packages 82 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/pi_bigint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the BigInt type 3 | */ 4 | "use strict"; 5 | 6 | /* return floor(log2(a)) for a > 0 and 0 for a = 0 */ 7 | function floor_log2(a) 8 | { 9 | var k_max, a1, k, i; 10 | k_max = 0n; 11 | while ((a >> (2n ** k_max)) != 0n) { 12 | k_max++; 13 | } 14 | k = 0n; 15 | a1 = a; 16 | for(i = k_max - 1n; i >= 0n; i--) { 17 | a1 = a >> (2n ** i); 18 | if (a1 != 0n) { 19 | a = a1; 20 | k |= (1n << i); 21 | } 22 | } 23 | return k; 24 | } 25 | 26 | /* return ceil(log2(a)) for a > 0 */ 27 | function ceil_log2(a) 28 | { 29 | return floor_log2(a - 1n) + 1n; 30 | } 31 | 32 | /* return floor(sqrt(a)) (not efficient but simple) */ 33 | function int_sqrt(a) 34 | { 35 | var l, u, s; 36 | if (a == 0n) 37 | return a; 38 | l = ceil_log2(a); 39 | u = 1n << ((l + 1n) / 2n); 40 | /* u >= floor(sqrt(a)) */ 41 | for(;;) { 42 | s = u; 43 | u = ((a / s) + s) / 2n; 44 | if (u >= s) 45 | break; 46 | } 47 | return s; 48 | } 49 | 50 | /* return pi * 2**prec */ 51 | function calc_pi(prec) { 52 | const CHUD_A = 13591409n; 53 | const CHUD_B = 545140134n; 54 | const CHUD_C = 640320n; 55 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */ 56 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ 57 | 58 | /* return [P, Q, G] */ 59 | function chud_bs(a, b, need_G) { 60 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; 61 | if (a == (b - 1n)) { 62 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); 63 | P = G * (CHUD_B * b + CHUD_A); 64 | if (b & 1n) 65 | P = -P; 66 | Q = b * b * b * CHUD_C3; 67 | } else { 68 | c = (a + b) >> 1n; 69 | [P1, Q1, G1] = chud_bs(a, c, true); 70 | [P2, Q2, G2] = chud_bs(c, b, need_G); 71 | P = P1 * Q2 + P2 * G1; 72 | Q = Q1 * Q2; 73 | if (need_G) 74 | G = G1 * G2; 75 | else 76 | G = 0n; 77 | } 78 | return [P, Q, G]; 79 | } 80 | 81 | var n, P, Q, G; 82 | /* number of serie terms */ 83 | n = BigInt(Math.ceil(Number(prec) / CHUD_BITS_PER_TERM)) + 10n; 84 | [P, Q, G] = chud_bs(0n, n, false); 85 | Q = (CHUD_C / 12n) * (Q << prec) / (P + Q * CHUD_A); 86 | G = int_sqrt(CHUD_C << (2n * prec)); 87 | return (Q * G) >> prec; 88 | } 89 | 90 | function main(args) { 91 | var r, n_digits, n_bits, out; 92 | if (args.length < 1) { 93 | print("usage: pi n_digits"); 94 | return; 95 | } 96 | n_digits = args[0] | 0; 97 | 98 | /* we add more bits to reduce the probability of bad rounding for 99 | the last digits */ 100 | n_bits = BigInt(Math.ceil(n_digits * Math.log2(10))) + 32n; 101 | r = calc_pi(n_bits); 102 | r = ((10n ** BigInt(n_digits)) * r) >> n_bits; 103 | out = r.toString(); 104 | print(out[0] + "." + out.slice(1)); 105 | } 106 | 107 | var args; 108 | if (typeof scriptArgs != "undefined") { 109 | args = scriptArgs; 110 | args.shift(); 111 | } else if (typeof arguments != "undefined") { 112 | args = arguments; 113 | } else { 114 | /* default: 1000 digits */ 115 | args=[1000]; 116 | } 117 | 118 | main(args); 119 | -------------------------------------------------------------------------------- /cxx/quickjs/tests/bjson.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: binary JSON module (test only) 3 | * 4 | * Copyright (c) 2017-2019 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs-libc.h" 25 | #include "../cutils.h" 26 | 27 | static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val, 28 | int argc, JSValueConst *argv) 29 | { 30 | uint8_t *buf; 31 | uint64_t pos, len; 32 | JSValue obj; 33 | size_t size; 34 | int flags; 35 | 36 | if (JS_ToIndex(ctx, &pos, argv[1])) 37 | return JS_EXCEPTION; 38 | if (JS_ToIndex(ctx, &len, argv[2])) 39 | return JS_EXCEPTION; 40 | buf = JS_GetArrayBuffer(ctx, &size, argv[0]); 41 | if (!buf) 42 | return JS_EXCEPTION; 43 | if (pos + len > size) 44 | return JS_ThrowRangeError(ctx, "array buffer overflow"); 45 | flags = 0; 46 | if (JS_ToBool(ctx, argv[3])) 47 | flags |= JS_READ_OBJ_REFERENCE; 48 | obj = JS_ReadObject(ctx, buf + pos, len, flags); 49 | return obj; 50 | } 51 | 52 | static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val, 53 | int argc, JSValueConst *argv) 54 | { 55 | size_t len; 56 | uint8_t *buf; 57 | JSValue array; 58 | int flags; 59 | 60 | flags = 0; 61 | if (JS_ToBool(ctx, argv[1])) 62 | flags |= JS_WRITE_OBJ_REFERENCE; 63 | buf = JS_WriteObject(ctx, &len, argv[0], flags); 64 | if (!buf) 65 | return JS_EXCEPTION; 66 | array = JS_NewArrayBufferCopy(ctx, buf, len); 67 | js_free(ctx, buf); 68 | return array; 69 | } 70 | 71 | static const JSCFunctionListEntry js_bjson_funcs[] = { 72 | JS_CFUNC_DEF("read", 4, js_bjson_read ), 73 | JS_CFUNC_DEF("write", 2, js_bjson_write ), 74 | }; 75 | 76 | static int js_bjson_init(JSContext *ctx, JSModuleDef *m) 77 | { 78 | return JS_SetModuleExportList(ctx, m, js_bjson_funcs, 79 | countof(js_bjson_funcs)); 80 | } 81 | 82 | #ifdef JS_SHARED_LIBRARY 83 | #define JS_INIT_MODULE js_init_module 84 | #else 85 | #define JS_INIT_MODULE js_init_module_bjson 86 | #endif 87 | 88 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) 89 | { 90 | JSModuleDef *m; 91 | m = JS_NewCModule(ctx, module_name, js_bjson_init); 92 | if (!m) 93 | return NULL; 94 | JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs)); 95 | return m; 96 | } 97 | -------------------------------------------------------------------------------- /cxx/quickjs/libregexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBREGEXP_H 25 | #define LIBREGEXP_H 26 | 27 | #include 28 | 29 | #include "libunicode.h" 30 | 31 | #define LRE_BOOL int /* for documentation purposes */ 32 | 33 | #define LRE_FLAG_GLOBAL (1 << 0) 34 | #define LRE_FLAG_IGNORECASE (1 << 1) 35 | #define LRE_FLAG_MULTILINE (1 << 2) 36 | #define LRE_FLAG_DOTALL (1 << 3) 37 | #define LRE_FLAG_UTF16 (1 << 4) 38 | #define LRE_FLAG_STICKY (1 << 5) 39 | 40 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ 41 | 42 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 43 | const char *buf, size_t buf_len, int re_flags, 44 | void *opaque); 45 | int lre_get_capture_count(const uint8_t *bc_buf); 46 | int lre_get_flags(const uint8_t *bc_buf); 47 | const char *lre_get_groupnames(const uint8_t *bc_buf); 48 | int lre_exec(uint8_t **capture, 49 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 50 | int cbuf_type, void *opaque); 51 | 52 | int lre_parse_escape(const uint8_t **pp, int allow_utf16); 53 | LRE_BOOL lre_is_space(int c); 54 | 55 | /* must be provided by the user */ 56 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 57 | void *lre_realloc(void *opaque, void *ptr, size_t size); 58 | 59 | /* JS identifier test */ 60 | extern uint32_t const lre_id_start_table_ascii[4]; 61 | extern uint32_t const lre_id_continue_table_ascii[4]; 62 | 63 | static inline int lre_js_is_ident_first(int c) 64 | { 65 | if ((uint32_t)c < 128) { 66 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; 67 | } else { 68 | #ifdef CONFIG_ALL_UNICODE 69 | return lre_is_id_start(c); 70 | #else 71 | return !lre_is_space(c); 72 | #endif 73 | } 74 | } 75 | 76 | static inline int lre_js_is_ident_next(int c) 77 | { 78 | if ((uint32_t)c < 128) { 79 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; 80 | } else { 81 | /* ZWNJ and ZWJ are accepted in identifiers */ 82 | #ifdef CONFIG_ALL_UNICODE 83 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; 84 | #else 85 | return !lre_is_space(c) || c == 0x200C || c == 0x200D; 86 | #endif 87 | } 88 | } 89 | 90 | #undef LRE_BOOL 91 | 92 | #endif /* LIBREGEXP_H */ 93 | -------------------------------------------------------------------------------- /ios/cxx/libregexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBREGEXP_H 25 | #define LIBREGEXP_H 26 | 27 | #include 28 | 29 | #include "libunicode.h" 30 | 31 | #define LRE_BOOL int /* for documentation purposes */ 32 | 33 | #define LRE_FLAG_GLOBAL (1 << 0) 34 | #define LRE_FLAG_IGNORECASE (1 << 1) 35 | #define LRE_FLAG_MULTILINE (1 << 2) 36 | #define LRE_FLAG_DOTALL (1 << 3) 37 | #define LRE_FLAG_UTF16 (1 << 4) 38 | #define LRE_FLAG_STICKY (1 << 5) 39 | 40 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ 41 | 42 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 43 | const char *buf, size_t buf_len, int re_flags, 44 | void *opaque); 45 | int lre_get_capture_count(const uint8_t *bc_buf); 46 | int lre_get_flags(const uint8_t *bc_buf); 47 | const char *lre_get_groupnames(const uint8_t *bc_buf); 48 | int lre_exec(uint8_t **capture, 49 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 50 | int cbuf_type, void *opaque); 51 | 52 | int lre_parse_escape(const uint8_t **pp, int allow_utf16); 53 | LRE_BOOL lre_is_space(int c); 54 | 55 | /* must be provided by the user */ 56 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 57 | void *lre_realloc(void *opaque, void *ptr, size_t size); 58 | 59 | /* JS identifier test */ 60 | extern uint32_t const lre_id_start_table_ascii[4]; 61 | extern uint32_t const lre_id_continue_table_ascii[4]; 62 | 63 | static inline int lre_js_is_ident_first(int c) 64 | { 65 | if ((uint32_t)c < 128) { 66 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; 67 | } else { 68 | #ifdef CONFIG_ALL_UNICODE 69 | return lre_is_id_start(c); 70 | #else 71 | return !lre_is_space(c); 72 | #endif 73 | } 74 | } 75 | 76 | static inline int lre_js_is_ident_next(int c) 77 | { 78 | if ((uint32_t)c < 128) { 79 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; 80 | } else { 81 | /* ZWNJ and ZWJ are accepted in identifiers */ 82 | #ifdef CONFIG_ALL_UNICODE 83 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; 84 | #else 85 | return !lre_is_space(c) || c == 0x200C || c == 0x200D; 86 | #endif 87 | } 88 | } 89 | 90 | #undef LRE_BOOL 91 | 92 | #endif /* LIBREGEXP_H */ 93 | -------------------------------------------------------------------------------- /macos/cxx/libregexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBREGEXP_H 25 | #define LIBREGEXP_H 26 | 27 | #include 28 | 29 | #include "libunicode.h" 30 | 31 | #define LRE_BOOL int /* for documentation purposes */ 32 | 33 | #define LRE_FLAG_GLOBAL (1 << 0) 34 | #define LRE_FLAG_IGNORECASE (1 << 1) 35 | #define LRE_FLAG_MULTILINE (1 << 2) 36 | #define LRE_FLAG_DOTALL (1 << 3) 37 | #define LRE_FLAG_UTF16 (1 << 4) 38 | #define LRE_FLAG_STICKY (1 << 5) 39 | 40 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ 41 | 42 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 43 | const char *buf, size_t buf_len, int re_flags, 44 | void *opaque); 45 | int lre_get_capture_count(const uint8_t *bc_buf); 46 | int lre_get_flags(const uint8_t *bc_buf); 47 | const char *lre_get_groupnames(const uint8_t *bc_buf); 48 | int lre_exec(uint8_t **capture, 49 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 50 | int cbuf_type, void *opaque); 51 | 52 | int lre_parse_escape(const uint8_t **pp, int allow_utf16); 53 | LRE_BOOL lre_is_space(int c); 54 | 55 | /* must be provided by the user */ 56 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 57 | void *lre_realloc(void *opaque, void *ptr, size_t size); 58 | 59 | /* JS identifier test */ 60 | extern uint32_t const lre_id_start_table_ascii[4]; 61 | extern uint32_t const lre_id_continue_table_ascii[4]; 62 | 63 | static inline int lre_js_is_ident_first(int c) 64 | { 65 | if ((uint32_t)c < 128) { 66 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; 67 | } else { 68 | #ifdef CONFIG_ALL_UNICODE 69 | return lre_is_id_start(c); 70 | #else 71 | return !lre_is_space(c); 72 | #endif 73 | } 74 | } 75 | 76 | static inline int lre_js_is_ident_next(int c) 77 | { 78 | if ((uint32_t)c < 128) { 79 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; 80 | } else { 81 | /* ZWNJ and ZWJ are accepted in identifiers */ 82 | #ifdef CONFIG_ALL_UNICODE 83 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; 84 | #else 85 | return !lre_is_space(c) || c == 0x200C || c == 0x200D; 86 | #endif 87 | } 88 | } 89 | 90 | #undef LRE_BOOL 91 | 92 | #endif /* LIBREGEXP_H */ 93 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /ios/cxx/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | #ifndef NULL 28 | #include 29 | #endif 30 | 31 | struct list_head { 32 | struct list_head *prev; 33 | struct list_head *next; 34 | }; 35 | 36 | #define LIST_HEAD_INIT(el) { &(el), &(el) } 37 | 38 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 39 | #define list_entry(el, type, member) \ 40 | ((type *)((uint8_t *)(el) - offsetof(type, member))) 41 | 42 | static inline void init_list_head(struct list_head *head) 43 | { 44 | head->prev = head; 45 | head->next = head; 46 | } 47 | 48 | /* insert 'el' between 'prev' and 'next' */ 49 | static inline void __list_add(struct list_head *el, 50 | struct list_head *prev, struct list_head *next) 51 | { 52 | prev->next = el; 53 | el->prev = prev; 54 | el->next = next; 55 | next->prev = el; 56 | } 57 | 58 | /* add 'el' at the head of the list 'head' (= after element head) */ 59 | static inline void list_add(struct list_head *el, struct list_head *head) 60 | { 61 | __list_add(el, head, head->next); 62 | } 63 | 64 | /* add 'el' at the end of the list 'head' (= before element head) */ 65 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 66 | { 67 | __list_add(el, head->prev, head); 68 | } 69 | 70 | static inline void list_del(struct list_head *el) 71 | { 72 | struct list_head *prev, *next; 73 | prev = el->prev; 74 | next = el->next; 75 | prev->next = next; 76 | next->prev = prev; 77 | el->prev = NULL; /* fail safe */ 78 | el->next = NULL; /* fail safe */ 79 | } 80 | 81 | static inline int list_empty(struct list_head *el) 82 | { 83 | return el->next == el; 84 | } 85 | 86 | #define list_for_each(el, head) \ 87 | for(el = (head)->next; el != (head); el = el->next) 88 | 89 | #define list_for_each_safe(el, el1, head) \ 90 | for(el = (head)->next, el1 = el->next; el != (head); \ 91 | el = el1, el1 = el->next) 92 | 93 | #define list_for_each_prev(el, head) \ 94 | for(el = (head)->prev; el != (head); el = el->prev) 95 | 96 | #define list_for_each_prev_safe(el, el1, head) \ 97 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 98 | el = el1, el1 = el->prev) 99 | 100 | #endif /* LIST_H */ 101 | -------------------------------------------------------------------------------- /macos/cxx/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | #ifndef NULL 28 | #include 29 | #endif 30 | 31 | struct list_head { 32 | struct list_head *prev; 33 | struct list_head *next; 34 | }; 35 | 36 | #define LIST_HEAD_INIT(el) { &(el), &(el) } 37 | 38 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 39 | #define list_entry(el, type, member) \ 40 | ((type *)((uint8_t *)(el) - offsetof(type, member))) 41 | 42 | static inline void init_list_head(struct list_head *head) 43 | { 44 | head->prev = head; 45 | head->next = head; 46 | } 47 | 48 | /* insert 'el' between 'prev' and 'next' */ 49 | static inline void __list_add(struct list_head *el, 50 | struct list_head *prev, struct list_head *next) 51 | { 52 | prev->next = el; 53 | el->prev = prev; 54 | el->next = next; 55 | next->prev = el; 56 | } 57 | 58 | /* add 'el' at the head of the list 'head' (= after element head) */ 59 | static inline void list_add(struct list_head *el, struct list_head *head) 60 | { 61 | __list_add(el, head, head->next); 62 | } 63 | 64 | /* add 'el' at the end of the list 'head' (= before element head) */ 65 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 66 | { 67 | __list_add(el, head->prev, head); 68 | } 69 | 70 | static inline void list_del(struct list_head *el) 71 | { 72 | struct list_head *prev, *next; 73 | prev = el->prev; 74 | next = el->next; 75 | prev->next = next; 76 | next->prev = prev; 77 | el->prev = NULL; /* fail safe */ 78 | el->next = NULL; /* fail safe */ 79 | } 80 | 81 | static inline int list_empty(struct list_head *el) 82 | { 83 | return el->next == el; 84 | } 85 | 86 | #define list_for_each(el, head) \ 87 | for(el = (head)->next; el != (head); el = el->next) 88 | 89 | #define list_for_each_safe(el, el1, head) \ 90 | for(el = (head)->next, el1 = el->next; el != (head); \ 91 | el = el1, el1 = el->next) 92 | 93 | #define list_for_each_prev(el, head) \ 94 | for(el = (head)->prev; el != (head); el = el->prev) 95 | 96 | #define list_for_each_prev_safe(el, el1, head) \ 97 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 98 | el = el1, el1 = el->prev) 99 | 100 | #endif /* LIST_H */ 101 | -------------------------------------------------------------------------------- /cxx/quickjs/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | #ifndef NULL 28 | #include 29 | #endif 30 | 31 | struct list_head { 32 | struct list_head *prev; 33 | struct list_head *next; 34 | }; 35 | 36 | #define LIST_HEAD_INIT(el) { &(el), &(el) } 37 | 38 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 39 | #define list_entry(el, type, member) \ 40 | ((type *)((uint8_t *)(el) - offsetof(type, member))) 41 | 42 | static inline void init_list_head(struct list_head *head) 43 | { 44 | head->prev = head; 45 | head->next = head; 46 | } 47 | 48 | /* insert 'el' between 'prev' and 'next' */ 49 | static inline void __list_add(struct list_head *el, 50 | struct list_head *prev, struct list_head *next) 51 | { 52 | prev->next = el; 53 | el->prev = prev; 54 | el->next = next; 55 | next->prev = el; 56 | } 57 | 58 | /* add 'el' at the head of the list 'head' (= after element head) */ 59 | static inline void list_add(struct list_head *el, struct list_head *head) 60 | { 61 | __list_add(el, head, head->next); 62 | } 63 | 64 | /* add 'el' at the end of the list 'head' (= before element head) */ 65 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 66 | { 67 | __list_add(el, head->prev, head); 68 | } 69 | 70 | static inline void list_del(struct list_head *el) 71 | { 72 | struct list_head *prev, *next; 73 | prev = el->prev; 74 | next = el->next; 75 | prev->next = next; 76 | next->prev = prev; 77 | el->prev = NULL; /* fail safe */ 78 | el->next = NULL; /* fail safe */ 79 | } 80 | 81 | static inline int list_empty(struct list_head *el) 82 | { 83 | return el->next == el; 84 | } 85 | 86 | #define list_for_each(el, head) \ 87 | for(el = (head)->next; el != (head); el = el->next) 88 | 89 | #define list_for_each_safe(el, el1, head) \ 90 | for(el = (head)->next, el1 = el->next; el != (head); \ 91 | el = el1, el1 = el->next) 92 | 93 | #define list_for_each_prev(el, head) \ 94 | for(el = (head)->prev; el != (head); el = el->prev) 95 | 96 | #define list_for_each_prev_safe(el, el1, head) \ 97 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 98 | el = el1, el1 = el->prev) 99 | 100 | #endif /* LIST_H */ 101 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /lib/src/plugins/timer.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: Allan 3 | * @Date: 2022-07-14 23:30:41 4 | * @Describe: js定时器实现 5 | */ 6 | 7 | import 'dart:async'; 8 | import 'dart:ffi' as ffi; 9 | import 'package:dart_quickjs/dart_quickjs.dart'; 10 | 11 | // 解析时间 12 | int _parseDuration(JSObject? time) { 13 | if (time is JSFloat) { 14 | return time.value.toInt(); 15 | } else if (time is JSNumber) { 16 | return time.value.toInt(); 17 | } else { 18 | return 0; 19 | } 20 | } 21 | 22 | class Clock { 23 | const Clock({ 24 | required this.timer, 25 | required this.callback, 26 | }); 27 | 28 | // 计时器 29 | final Timer timer; 30 | // 回调 31 | final JSFunction callback; 32 | } 33 | 34 | abstract class Interval extends Plugin { 35 | // 回调函数 36 | final Map clocks = {}; 37 | // 上下文 38 | late ffi.Pointer context; 39 | 40 | @override 41 | void destroy(Runtime runtime) { 42 | clocks.forEach((id, clock) { 43 | // 停止 44 | clock.timer.cancel(); 45 | // 释放js函数 46 | clock.callback.free(); 47 | }); 48 | 49 | clocks.clear(); 50 | } 51 | 52 | // 创建 53 | JSNumber createTimer(JSFunction callback, [JSObject? time]); 54 | 55 | // 清除 56 | void clear(JSObject? data) { 57 | // 获取id 58 | final id = _parseDuration(data); 59 | final clock = clocks[id]; 60 | 61 | if (clock != null) { 62 | // 停止 63 | clock.timer.cancel(); 64 | // 释放js函数 65 | clock.callback.free(); 66 | // 移除 67 | clocks.remove(id); 68 | } 69 | } 70 | } 71 | 72 | // 定时器 73 | class SetInterval extends Interval { 74 | late Runtime _runtime; 75 | 76 | @override 77 | void onCreate(Runtime runtime) { 78 | final global = runtime.global; 79 | _runtime = runtime; 80 | context = _runtime.context; 81 | global.setPropertyStr( 82 | 'setInterval', 83 | JSFunction.create(context, createTimer), 84 | ); 85 | global.setPropertyStr('clearInterval', JSFunction.create(context, clear)); 86 | } 87 | 88 | @override 89 | JSNumber createTimer(JSFunction callback, [JSObject? time]) { 90 | // 标记引用 - 需后续手动回收 91 | callback.dupValue(); 92 | 93 | // 时间 94 | final duration = _parseDuration(time); 95 | // 定时器 96 | final timer = Timer.periodic( 97 | Duration(milliseconds: duration), 98 | (timer) { 99 | callback.call(); 100 | _runtime.dispatch(); 101 | }, 102 | ); 103 | // 定时器key - 唯一 104 | final int key = timer.hashCode; 105 | 106 | clocks[key] = Clock(timer: timer, callback: callback); 107 | 108 | return JSNumber.create(context, key); 109 | } 110 | } 111 | 112 | // 计时器 113 | class SetTimeout extends Interval { 114 | late Runtime _runtime; 115 | 116 | @override 117 | void onCreate(Runtime runtime) { 118 | final global = runtime.global; 119 | _runtime = runtime; 120 | context = _runtime.context; 121 | global.setPropertyStr( 122 | 'setTimeout', 123 | JSFunction.create(context, createTimer), 124 | ); 125 | global.setPropertyStr('clearTimeout', JSFunction.create(context, clear)); 126 | } 127 | 128 | @override 129 | JSNumber createTimer(JSFunction callback, [JSObject? time]) { 130 | // 标记引用 - 需后续手动回收 131 | callback.dupValue(); 132 | // 定时器key - 唯一 133 | final int key = DateTime.now().microsecondsSinceEpoch; 134 | // 地址 135 | final JSNumber id = JSNumber.create(context, key); 136 | // 时间 137 | final duration = _parseDuration(time); 138 | // 定时器 139 | final timer = Timer( 140 | Duration(milliseconds: duration), 141 | () { 142 | callback.call(); 143 | clear(id); 144 | _runtime.dispatch(); 145 | }, 146 | ); 147 | 148 | clocks[key] = Clock(timer: timer, callback: callback); 149 | return id; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /ios/cxx/ffi.h: -------------------------------------------------------------------------------- 1 | #include "quickjs.h" 2 | #include 3 | 4 | #ifdef _MSC_VER 5 | #define DART_EXPORT __declspec(dllexport) 6 | #else 7 | #define DART_EXPORT __attribute__((visibility("default"))) __attribute__((used)) 8 | #endif 9 | 10 | // 通道 11 | typedef JSValue *CHANNEL(JSContext *ctx, const char *symbol, int32_t argc, JSValueConst *argv); 12 | 13 | extern "C" { 14 | // 设置通道 15 | DART_EXPORT void SetChannel(JSRuntime *runtime, CHANNEL channel); 16 | 17 | // 启用模块加载 18 | DART_EXPORT void EnableModuleLoader(JSRuntime *runtime); 19 | 20 | // 获取全局对象 21 | DART_EXPORT JSValue *GetGlobalObject(JSContext *ctx); 22 | 23 | // 编译字节码 24 | DART_EXPORT uint8_t *CompileScript(JSContext *ctx, const char *script, const char *fileName, size_t *lengthPtr); 25 | 26 | // 运行字节码 27 | DART_EXPORT JSValue *EvaluateBytecode(JSContext *ctx, size_t length, uint8_t *buf); 28 | 29 | // 执行js代码 30 | DART_EXPORT JSValue *EvaluateJavaScript(JSContext *ctx, const char *script, const char *fileName, int32_t flags); 31 | 32 | // 获取js value的大小 33 | DART_EXPORT uint32_t JSValueSizeOf(); 34 | 35 | // 根据下标设置value 36 | DART_EXPORT void SetValueAt(JSValue *data, uint32_t index, JSValue *value); 37 | 38 | // 获取异常 39 | DART_EXPORT JSValue *GetException(JSContext *ctx); 40 | 41 | // 执行挂起任务 42 | DART_EXPORT int32_t ExecutePendingJob(JSRuntime *runtime); 43 | 44 | // 创建对象 45 | DART_EXPORT JSValue *NewObject(JSContext *ctx); 46 | 47 | // 创建字符串 48 | DART_EXPORT JSValue *NewString(JSContext *ctx, const char *data); 49 | 50 | // 创建int64 51 | DART_EXPORT JSValue *NewInt64(JSContext *ctx, int64_t value); 52 | 53 | // 创建float64 54 | DART_EXPORT JSValue *NewFloat64(JSContext *ctx, double value); 55 | 56 | // 创建bool 57 | DART_EXPORT JSValue *NewBool(JSContext *ctx, int32_t value); 58 | 59 | // 创建数组 60 | DART_EXPORT JSValue *NewArray(JSContext *ctx); 61 | 62 | // 创建promise 63 | DART_EXPORT JSValue *NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs); 64 | 65 | // 创建js方法 66 | DART_EXPORT JSValue *NewCFunctionData(JSContext *ctx, const char *symbol); 67 | 68 | // 创建null 69 | DART_EXPORT JSValue *NewNull(); 70 | 71 | // 创建undefined 72 | DART_EXPORT JSValue *NewUndefined(); 73 | 74 | // 添加属性 - key为string类型 75 | DART_EXPORT int32_t SetPropertyStr(JSContext *ctx, JSValueConst *obj, const char *key, JSValue *value); 76 | 77 | // 添加属性 - key为js value 78 | DART_EXPORT int32_t SetProperty(JSContext *ctx, JSValueConst *obj, JSValueConst *key, JSValueConst *value, int flags); 79 | 80 | // 添加属性 - key为uint32 81 | DART_EXPORT int DefinePropertyValueUint32(JSContext *ctx, JSValueConst *obj, uint32_t index, JSValue *value, int32_t flags); 82 | 83 | // 读取属性 - key为string类型 84 | JSValue *GetPropertyStr(JSContext *ctx, JSValueConst *obj, const char *prop); 85 | 86 | // 读取属性 - key为js value 87 | DART_EXPORT JSValue *GetProperty(JSContext *ctx, JSValueConst *obj, JSValueConst *key); 88 | 89 | // 增加引用标记 90 | DART_EXPORT JSValue *JSDupValue(JSContext *ctx, JSValueConst *value); 91 | 92 | // 释放js value 93 | DART_EXPORT void JSFreeValue(JSContext *ctx, JSValue *value); 94 | 95 | // 释放运行时 96 | DART_EXPORT void FreeRuntime(JSRuntime *runtime); 97 | 98 | // js value转string 99 | DART_EXPORT const char *JSToCString(JSContext *ctx, JSValueConst *value); 100 | 101 | // 转int 64 102 | DART_EXPORT int64_t JSToInt64(JSContext *ctx, JSValueConst *value); 103 | 104 | // 转Float 64 105 | DART_EXPORT double JSToFloat64(JSContext *ctx, JSValueConst *value); 106 | 107 | // 转布尔值 108 | DART_EXPORT int32_t JSToBool(JSContext *ctx, JSValueConst *value); 109 | 110 | // 调用js方法 111 | DART_EXPORT JSValue *CallFuncton(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj, int32_t argc, JSValueConst *argv); 112 | 113 | // 是否是数组 114 | DART_EXPORT int32_t IsArray(JSContext *ctx, JSValueConst *value); 115 | 116 | // 是否是函数 117 | DART_EXPORT int32_t IsFunction(JSContext *ctx, JSValueConst *value); 118 | 119 | // 是否是promise 120 | DART_EXPORT int32_t IsPromise(JSContext *ctx, JSValueConst *value); 121 | } 122 | -------------------------------------------------------------------------------- /cxx/quickjs/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Release the QuickJS source code 3 | 4 | set -e 5 | 6 | version=`cat VERSION` 7 | 8 | if [ "$1" = "-h" ] ; then 9 | echo "release.sh [release_list]" 10 | echo "" 11 | echo "release_list: extras binary win_binary quickjs" 12 | 13 | exit 1 14 | fi 15 | 16 | release_list="extras binary win_binary quickjs" 17 | 18 | if [ "$1" != "" ] ; then 19 | release_list="$1" 20 | fi 21 | 22 | #################################################" 23 | # extras 24 | 25 | if echo $release_list | grep -w -q extras ; then 26 | 27 | d="quickjs-${version}" 28 | name="quickjs-extras-${version}" 29 | outdir="/tmp/${d}" 30 | 31 | rm -rf $outdir 32 | mkdir -p $outdir $outdir/unicode $outdir/tests 33 | 34 | cp unicode/* $outdir/unicode 35 | cp -a tests/bench-v8 $outdir/tests 36 | 37 | ( cd /tmp && tar Jcvf /tmp/${name}.tar.xz ${d} ) 38 | 39 | fi 40 | 41 | #################################################" 42 | # Windows binary release 43 | 44 | if echo $release_list | grep -w -q win_binary ; then 45 | 46 | # win64 47 | 48 | dlldir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin 49 | cross_prefix="x86_64-w64-mingw32-" 50 | d="quickjs-win-x86_64-${version}" 51 | outdir="/tmp/${d}" 52 | 53 | rm -rf $outdir 54 | mkdir -p $outdir 55 | 56 | make CONFIG_WIN32=y qjs.exe 57 | cp qjs.exe $outdir 58 | ${cross_prefix}strip $outdir/qjs.exe 59 | cp $dlldir/libwinpthread-1.dll $outdir 60 | 61 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 62 | 63 | make CONFIG_WIN32=y clean 64 | 65 | # win32 66 | 67 | dlldir=/usr/i686-w64-mingw32/sys-root/mingw/bin 68 | cross_prefix="i686-w64-mingw32-" 69 | d="quickjs-win-i686-${version}" 70 | outdir="/tmp/${d}" 71 | 72 | rm -rf $outdir 73 | mkdir -p $outdir 74 | 75 | make clean 76 | make CONFIG_WIN32=y clean 77 | 78 | make CONFIG_WIN32=y CONFIG_M32=y qjs.exe 79 | cp qjs.exe $outdir 80 | ${cross_prefix}strip $outdir/qjs.exe 81 | cp $dlldir/libwinpthread-1.dll $outdir 82 | 83 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 84 | 85 | fi 86 | 87 | #################################################" 88 | # Linux binary release 89 | 90 | if echo $release_list | grep -w -q binary ; then 91 | 92 | make clean 93 | make CONFIG_WIN32=y clean 94 | make -j4 qjs run-test262 95 | make -j4 CONFIG_M32=y qjs32 run-test262-32 96 | strip qjs run-test262 qjs32 run-test262-32 97 | 98 | d="quickjs-linux-x86_64-${version}" 99 | outdir="/tmp/${d}" 100 | 101 | rm -rf $outdir 102 | mkdir -p $outdir 103 | 104 | cp qjs run-test262 $outdir 105 | 106 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 107 | 108 | d="quickjs-linux-i686-${version}" 109 | outdir="/tmp/${d}" 110 | 111 | rm -rf $outdir 112 | mkdir -p $outdir 113 | 114 | cp qjs32 $outdir/qjs 115 | cp run-test262-32 $outdir/run-test262 116 | 117 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 118 | 119 | fi 120 | 121 | #################################################" 122 | # quickjs 123 | 124 | if echo $release_list | grep -w -q quickjs ; then 125 | 126 | make build_doc 127 | 128 | d="quickjs-${version}" 129 | outdir="/tmp/${d}" 130 | 131 | rm -rf $outdir 132 | mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples 133 | 134 | cp Makefile VERSION TODO Changelog readme.txt LICENSE \ 135 | release.sh unicode_download.sh \ 136 | qjs.c qjsc.c qjscalc.js repl.js \ 137 | quickjs.c quickjs.h quickjs-atom.h \ 138 | quickjs-libc.c quickjs-libc.h quickjs-opcode.h \ 139 | cutils.c cutils.h list.h \ 140 | libregexp.c libregexp.h libregexp-opcode.h \ 141 | libunicode.c libunicode.h libunicode-table.h \ 142 | libbf.c libbf.h \ 143 | unicode_gen.c unicode_gen_def.h \ 144 | run-test262.c test262o.conf test262.conf \ 145 | test262o_errors.txt test262_errors.txt \ 146 | $outdir 147 | 148 | cp tests/*.js tests/*.patch tests/bjson.c $outdir/tests 149 | 150 | cp examples/*.js examples/*.c $outdir/examples 151 | 152 | cp doc/quickjs.texi doc/quickjs.pdf doc/quickjs.html \ 153 | doc/jsbignum.texi doc/jsbignum.html doc/jsbignum.pdf \ 154 | $outdir/doc 155 | 156 | ( cd /tmp && tar Jcvf /tmp/${d}.tar.xz ${d} ) 157 | 158 | fi 159 | -------------------------------------------------------------------------------- /ios/cxx/libunicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Unicode utilities 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBUNICODE_H 25 | #define LIBUNICODE_H 26 | 27 | #include 28 | 29 | #define LRE_BOOL int /* for documentation purposes */ 30 | 31 | /* define it to include all the unicode tables (40KB larger) */ 32 | #define CONFIG_ALL_UNICODE 33 | 34 | #define LRE_CC_RES_LEN_MAX 3 35 | 36 | typedef enum { 37 | UNICODE_NFC, 38 | UNICODE_NFD, 39 | UNICODE_NFKC, 40 | UNICODE_NFKD, 41 | } UnicodeNormalizationEnum; 42 | 43 | int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 44 | LRE_BOOL lre_is_cased(uint32_t c); 45 | LRE_BOOL lre_is_case_ignorable(uint32_t c); 46 | 47 | /* char ranges */ 48 | 49 | typedef struct { 50 | int len; /* in points, always even */ 51 | int size; 52 | uint32_t *points; /* points sorted by increasing value */ 53 | void *mem_opaque; 54 | void *(*realloc_func)(void *opaque, void *ptr, size_t size); 55 | } CharRange; 56 | 57 | typedef enum { 58 | CR_OP_UNION, 59 | CR_OP_INTER, 60 | CR_OP_XOR, 61 | } CharRangeOpEnum; 62 | 63 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 64 | void cr_free(CharRange *cr); 65 | int cr_realloc(CharRange *cr, int size); 66 | int cr_copy(CharRange *cr, const CharRange *cr1); 67 | 68 | static inline int cr_add_point(CharRange *cr, uint32_t v) 69 | { 70 | if (cr->len >= cr->size) { 71 | if (cr_realloc(cr, cr->len + 1)) 72 | return -1; 73 | } 74 | cr->points[cr->len++] = v; 75 | return 0; 76 | } 77 | 78 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) 79 | { 80 | if ((cr->len + 2) > cr->size) { 81 | if (cr_realloc(cr, cr->len + 2)) 82 | return -1; 83 | } 84 | cr->points[cr->len++] = c1; 85 | cr->points[cr->len++] = c2; 86 | return 0; 87 | } 88 | 89 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); 90 | 91 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) 92 | { 93 | uint32_t b_pt[2]; 94 | b_pt[0] = c1; 95 | b_pt[1] = c2 + 1; 96 | return cr_union1(cr, b_pt, 2); 97 | } 98 | 99 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, 100 | const uint32_t *b_pt, int b_len, int op); 101 | 102 | int cr_invert(CharRange *cr); 103 | 104 | #ifdef CONFIG_ALL_UNICODE 105 | 106 | LRE_BOOL lre_is_id_start(uint32_t c); 107 | LRE_BOOL lre_is_id_continue(uint32_t c); 108 | 109 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, 110 | UnicodeNormalizationEnum n_type, 111 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 112 | 113 | /* Unicode character range functions */ 114 | 115 | int unicode_script(CharRange *cr, 116 | const char *script_name, LRE_BOOL is_ext); 117 | int unicode_general_category(CharRange *cr, const char *gc_name); 118 | int unicode_prop(CharRange *cr, const char *prop_name); 119 | 120 | #endif /* CONFIG_ALL_UNICODE */ 121 | 122 | #undef LRE_BOOL 123 | 124 | #endif /* LIBUNICODE_H */ 125 | -------------------------------------------------------------------------------- /cxx/quickjs/libunicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Unicode utilities 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBUNICODE_H 25 | #define LIBUNICODE_H 26 | 27 | #include 28 | 29 | #define LRE_BOOL int /* for documentation purposes */ 30 | 31 | /* define it to include all the unicode tables (40KB larger) */ 32 | #define CONFIG_ALL_UNICODE 33 | 34 | #define LRE_CC_RES_LEN_MAX 3 35 | 36 | typedef enum { 37 | UNICODE_NFC, 38 | UNICODE_NFD, 39 | UNICODE_NFKC, 40 | UNICODE_NFKD, 41 | } UnicodeNormalizationEnum; 42 | 43 | int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 44 | LRE_BOOL lre_is_cased(uint32_t c); 45 | LRE_BOOL lre_is_case_ignorable(uint32_t c); 46 | 47 | /* char ranges */ 48 | 49 | typedef struct { 50 | int len; /* in points, always even */ 51 | int size; 52 | uint32_t *points; /* points sorted by increasing value */ 53 | void *mem_opaque; 54 | void *(*realloc_func)(void *opaque, void *ptr, size_t size); 55 | } CharRange; 56 | 57 | typedef enum { 58 | CR_OP_UNION, 59 | CR_OP_INTER, 60 | CR_OP_XOR, 61 | } CharRangeOpEnum; 62 | 63 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 64 | void cr_free(CharRange *cr); 65 | int cr_realloc(CharRange *cr, int size); 66 | int cr_copy(CharRange *cr, const CharRange *cr1); 67 | 68 | static inline int cr_add_point(CharRange *cr, uint32_t v) 69 | { 70 | if (cr->len >= cr->size) { 71 | if (cr_realloc(cr, cr->len + 1)) 72 | return -1; 73 | } 74 | cr->points[cr->len++] = v; 75 | return 0; 76 | } 77 | 78 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) 79 | { 80 | if ((cr->len + 2) > cr->size) { 81 | if (cr_realloc(cr, cr->len + 2)) 82 | return -1; 83 | } 84 | cr->points[cr->len++] = c1; 85 | cr->points[cr->len++] = c2; 86 | return 0; 87 | } 88 | 89 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); 90 | 91 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) 92 | { 93 | uint32_t b_pt[2]; 94 | b_pt[0] = c1; 95 | b_pt[1] = c2 + 1; 96 | return cr_union1(cr, b_pt, 2); 97 | } 98 | 99 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, 100 | const uint32_t *b_pt, int b_len, int op); 101 | 102 | int cr_invert(CharRange *cr); 103 | 104 | #ifdef CONFIG_ALL_UNICODE 105 | 106 | LRE_BOOL lre_is_id_start(uint32_t c); 107 | LRE_BOOL lre_is_id_continue(uint32_t c); 108 | 109 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, 110 | UnicodeNormalizationEnum n_type, 111 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 112 | 113 | /* Unicode character range functions */ 114 | 115 | int unicode_script(CharRange *cr, 116 | const char *script_name, LRE_BOOL is_ext); 117 | int unicode_general_category(CharRange *cr, const char *gc_name); 118 | int unicode_prop(CharRange *cr, const char *prop_name); 119 | 120 | #endif /* CONFIG_ALL_UNICODE */ 121 | 122 | #undef LRE_BOOL 123 | 124 | #endif /* LIBUNICODE_H */ 125 | -------------------------------------------------------------------------------- /macos/cxx/libunicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Unicode utilities 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBUNICODE_H 25 | #define LIBUNICODE_H 26 | 27 | #include 28 | 29 | #define LRE_BOOL int /* for documentation purposes */ 30 | 31 | /* define it to include all the unicode tables (40KB larger) */ 32 | #define CONFIG_ALL_UNICODE 33 | 34 | #define LRE_CC_RES_LEN_MAX 3 35 | 36 | typedef enum { 37 | UNICODE_NFC, 38 | UNICODE_NFD, 39 | UNICODE_NFKC, 40 | UNICODE_NFKD, 41 | } UnicodeNormalizationEnum; 42 | 43 | int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 44 | LRE_BOOL lre_is_cased(uint32_t c); 45 | LRE_BOOL lre_is_case_ignorable(uint32_t c); 46 | 47 | /* char ranges */ 48 | 49 | typedef struct { 50 | int len; /* in points, always even */ 51 | int size; 52 | uint32_t *points; /* points sorted by increasing value */ 53 | void *mem_opaque; 54 | void *(*realloc_func)(void *opaque, void *ptr, size_t size); 55 | } CharRange; 56 | 57 | typedef enum { 58 | CR_OP_UNION, 59 | CR_OP_INTER, 60 | CR_OP_XOR, 61 | } CharRangeOpEnum; 62 | 63 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 64 | void cr_free(CharRange *cr); 65 | int cr_realloc(CharRange *cr, int size); 66 | int cr_copy(CharRange *cr, const CharRange *cr1); 67 | 68 | static inline int cr_add_point(CharRange *cr, uint32_t v) 69 | { 70 | if (cr->len >= cr->size) { 71 | if (cr_realloc(cr, cr->len + 1)) 72 | return -1; 73 | } 74 | cr->points[cr->len++] = v; 75 | return 0; 76 | } 77 | 78 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) 79 | { 80 | if ((cr->len + 2) > cr->size) { 81 | if (cr_realloc(cr, cr->len + 2)) 82 | return -1; 83 | } 84 | cr->points[cr->len++] = c1; 85 | cr->points[cr->len++] = c2; 86 | return 0; 87 | } 88 | 89 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); 90 | 91 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) 92 | { 93 | uint32_t b_pt[2]; 94 | b_pt[0] = c1; 95 | b_pt[1] = c2 + 1; 96 | return cr_union1(cr, b_pt, 2); 97 | } 98 | 99 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, 100 | const uint32_t *b_pt, int b_len, int op); 101 | 102 | int cr_invert(CharRange *cr); 103 | 104 | #ifdef CONFIG_ALL_UNICODE 105 | 106 | LRE_BOOL lre_is_id_start(uint32_t c); 107 | LRE_BOOL lre_is_id_continue(uint32_t c); 108 | 109 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, 110 | UnicodeNormalizationEnum n_type, 111 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 112 | 113 | /* Unicode character range functions */ 114 | 115 | int unicode_script(CharRange *cr, 116 | const char *script_name, LRE_BOOL is_ext); 117 | int unicode_general_category(CharRange *cr, const char *gc_name); 118 | int unicode_prop(CharRange *cr, const char *prop_name); 119 | 120 | #endif /* CONFIG_ALL_UNICODE */ 121 | 122 | #undef LRE_BOOL 123 | 124 | #endif /* LIBUNICODE_H */ 125 | -------------------------------------------------------------------------------- /macos/cxx/ffi.h: -------------------------------------------------------------------------------- 1 | #include "quickjs.h" 2 | #include 3 | 4 | #ifdef _MSC_VER 5 | #define DART_EXPORT __declspec(dllexport) 6 | #else 7 | #define DART_EXPORT __attribute__((visibility("default"))) __attribute__((used)) 8 | #endif 9 | 10 | // 通道 11 | typedef JSValue *CHANNEL(JSContext *ctx, const char *symbol, int32_t argc, JSValueConst *argv); 12 | 13 | extern "C" { 14 | // 设置通道 15 | DART_EXPORT void SetChannel(JSRuntime *runtime, CHANNEL channel); 16 | 17 | // 启用模块加载 18 | DART_EXPORT void EnableModuleLoader(JSRuntime *runtime); 19 | 20 | // 获取全局对象 21 | DART_EXPORT JSValue *GetGlobalObject(JSContext *ctx); 22 | 23 | // 编译字节码 24 | DART_EXPORT uint8_t *CompileScript(JSContext *ctx, const char *script, const char *fileName, size_t *lengthPtr); 25 | 26 | // 运行字节码 27 | DART_EXPORT JSValue *EvaluateBytecode(JSContext *ctx, size_t length, uint8_t *buf); 28 | 29 | // 执行js代码 30 | DART_EXPORT JSValue *EvaluateJavaScript(JSContext *ctx, const char *script, const char *fileName, int32_t flags); 31 | 32 | // 获取js value的大小 33 | DART_EXPORT uint32_t JSValueSizeOf(); 34 | 35 | // 根据下标设置value 36 | DART_EXPORT void SetValueAt(JSValue *data, uint32_t index, JSValue *value); 37 | 38 | // 获取异常 39 | DART_EXPORT JSValue *GetException(JSContext *ctx); 40 | 41 | // 执行挂起任务 42 | DART_EXPORT int32_t ExecutePendingJob(JSRuntime *runtime); 43 | 44 | // 创建对象 45 | DART_EXPORT JSValue *NewObject(JSContext *ctx); 46 | 47 | // 创建字符串 48 | DART_EXPORT JSValue *NewString(JSContext *ctx, const char *data); 49 | 50 | // 创建int64 51 | DART_EXPORT JSValue *NewInt64(JSContext *ctx, int64_t value); 52 | 53 | // 创建float64 54 | DART_EXPORT JSValue *NewFloat64(JSContext *ctx, double value); 55 | 56 | // 创建bool 57 | DART_EXPORT JSValue *NewBool(JSContext *ctx, int32_t value); 58 | 59 | // 创建数组 60 | DART_EXPORT JSValue *NewArray(JSContext *ctx); 61 | 62 | // 创建promise 63 | DART_EXPORT JSValue *NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs); 64 | 65 | // 创建js方法 66 | DART_EXPORT JSValue *NewCFunctionData(JSContext *ctx, const char *symbol); 67 | 68 | // 创建null 69 | DART_EXPORT JSValue *NewNull(); 70 | 71 | // 创建undefined 72 | DART_EXPORT JSValue *NewUndefined(); 73 | 74 | // 添加属性 - key为string类型 75 | DART_EXPORT int32_t SetPropertyStr(JSContext *ctx, JSValueConst *obj, const char *key, JSValue *value); 76 | 77 | // 添加属性 - key为js value 78 | DART_EXPORT int32_t SetProperty(JSContext *ctx, JSValueConst *obj, JSValueConst *key, JSValueConst *value, int flags); 79 | 80 | // 添加属性 - key为uint32 81 | DART_EXPORT int DefinePropertyValueUint32(JSContext *ctx, JSValueConst *obj, uint32_t index, JSValue *value, int32_t flags); 82 | 83 | // 读取属性 - key为string类型 84 | JSValue *GetPropertyStr(JSContext *ctx, JSValueConst *obj, const char *prop); 85 | 86 | // 读取属性 - key为js value 87 | DART_EXPORT JSValue *GetProperty(JSContext *ctx, JSValueConst *obj, JSValueConst *key); 88 | 89 | // 增加引用标记 90 | DART_EXPORT JSValue *JSDupValue(JSContext *ctx, JSValueConst *value); 91 | 92 | // 释放js value 93 | DART_EXPORT void JSFreeValue(JSContext *ctx, JSValue *value); 94 | 95 | // 释放运行时 96 | DART_EXPORT void FreeRuntime(JSRuntime *runtime); 97 | 98 | // js value转string 99 | DART_EXPORT const char *JSToCString(JSContext *ctx, JSValueConst *value); 100 | 101 | // 转int 64 102 | DART_EXPORT int64_t JSToInt64(JSContext *ctx, JSValueConst *value); 103 | 104 | // 转Float 64 105 | DART_EXPORT double JSToFloat64(JSContext *ctx, JSValueConst *value); 106 | 107 | // 转布尔值 108 | DART_EXPORT int32_t JSToBool(JSContext *ctx, JSValueConst *value); 109 | 110 | // 调用js方法 111 | DART_EXPORT JSValue *CallFuncton(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj, int32_t argc, JSValueConst *argv); 112 | 113 | // 调用构造函数 114 | DART_EXPORT JSValue *CallConstructor(JSContext *ctx, JSValueConst *func_obj, int argc, JSValueConst *argv); 115 | 116 | // 是否是数组 117 | DART_EXPORT int32_t IsArray(JSContext *ctx, JSValueConst *value); 118 | 119 | // 是否是函数 120 | DART_EXPORT int32_t IsFunction(JSContext *ctx, JSValueConst *value); 121 | 122 | // 是否是promise 123 | DART_EXPORT int32_t IsPromise(JSContext *ctx, JSValueConst *value); 124 | 125 | // 是否是构造函数 126 | DART_EXPORT int32_t IsConstructor(JSContext *ctx, JSValueConst *value); 127 | } 128 | -------------------------------------------------------------------------------- /cxx/ffi.h: -------------------------------------------------------------------------------- 1 | #include "quickjs/quickjs.h" 2 | #include 3 | 4 | #ifdef _MSC_VER 5 | #define DART_EXPORT __declspec(dllexport) 6 | #else 7 | #define DART_EXPORT __attribute__((visibility("default"))) __attribute__((used)) 8 | #endif 9 | 10 | // 通道 11 | typedef JSValue *CHANNEL(JSContext *ctx, const char *symbol, int32_t argc, JSValueConst *argv); 12 | 13 | extern "C" { 14 | // 设置通道 15 | DART_EXPORT void SetChannel(JSRuntime *runtime, CHANNEL channel); 16 | 17 | // 启用模块加载 18 | DART_EXPORT void EnableModuleLoader(JSRuntime *runtime); 19 | 20 | // 获取全局对象 21 | DART_EXPORT JSValue *GetGlobalObject(JSContext *ctx); 22 | 23 | // 编译字节码 24 | DART_EXPORT uint8_t *CompileScript(JSContext *ctx, const char *script, const char *fileName, size_t *lengthPtr); 25 | 26 | // 运行字节码 27 | DART_EXPORT JSValue *EvaluateBytecode(JSContext *ctx, size_t length, uint8_t *buf); 28 | 29 | // 执行js代码 30 | DART_EXPORT JSValue *EvaluateJavaScript(JSContext *ctx, const char *script, const char *fileName, int32_t flags); 31 | 32 | // 获取js value的大小 33 | DART_EXPORT uint32_t JSValueSizeOf(); 34 | 35 | // 根据下标设置value 36 | DART_EXPORT void SetValueAt(JSValue *data, uint32_t index, JSValue *value); 37 | 38 | // 获取异常 39 | DART_EXPORT JSValue *GetException(JSContext *ctx); 40 | 41 | // 执行挂起任务 42 | DART_EXPORT int32_t ExecutePendingJob(JSRuntime *runtime); 43 | 44 | // 创建对象 45 | DART_EXPORT JSValue *NewObject(JSContext *ctx); 46 | 47 | // 创建字符串 48 | DART_EXPORT JSValue *NewString(JSContext *ctx, const char *data); 49 | 50 | // 创建int64 51 | DART_EXPORT JSValue *NewInt64(JSContext *ctx, int64_t value); 52 | 53 | // 创建float64 54 | DART_EXPORT JSValue *NewFloat64(JSContext *ctx, double value); 55 | 56 | // 创建bool 57 | DART_EXPORT JSValue *NewBool(JSContext *ctx, int32_t value); 58 | 59 | // 创建数组 60 | DART_EXPORT JSValue *NewArray(JSContext *ctx); 61 | 62 | // 创建promise 63 | DART_EXPORT JSValue *NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs); 64 | 65 | // 创建js方法 66 | DART_EXPORT JSValue *NewCFunctionData(JSContext *ctx, const char *symbol); 67 | 68 | // 创建null 69 | DART_EXPORT JSValue *NewNull(); 70 | 71 | // 创建undefined 72 | DART_EXPORT JSValue *NewUndefined(); 73 | 74 | // 添加属性 - key为string类型 75 | DART_EXPORT int32_t SetPropertyStr(JSContext *ctx, JSValueConst *obj, const char *key, JSValue *value); 76 | 77 | // 添加属性 - key为js value 78 | DART_EXPORT int32_t SetProperty(JSContext *ctx, JSValueConst *obj, JSValueConst *key, JSValueConst *value, int flags); 79 | 80 | // 添加属性 - key为uint32 81 | DART_EXPORT int DefinePropertyValueUint32(JSContext *ctx, JSValueConst *obj, uint32_t index, JSValue *value, int32_t flags); 82 | 83 | // 读取属性 - key为string类型 84 | JSValue *GetPropertyStr(JSContext *ctx, JSValueConst *obj, const char *prop); 85 | 86 | // 读取属性 - key为js value 87 | DART_EXPORT JSValue *GetProperty(JSContext *ctx, JSValueConst *obj, JSValueConst *key); 88 | 89 | // 增加引用标记 90 | DART_EXPORT JSValue *JSDupValue(JSContext *ctx, JSValueConst *value); 91 | 92 | // 释放js value 93 | DART_EXPORT void JSFreeValue(JSContext *ctx, JSValue *value); 94 | 95 | // 释放运行时 96 | DART_EXPORT void FreeRuntime(JSRuntime *runtime); 97 | 98 | // js value转string 99 | DART_EXPORT const char *JSToCString(JSContext *ctx, JSValueConst *value); 100 | 101 | // 转int 64 102 | DART_EXPORT int64_t JSToInt64(JSContext *ctx, JSValueConst *value); 103 | 104 | // 转Float 64 105 | DART_EXPORT double JSToFloat64(JSContext *ctx, JSValueConst *value); 106 | 107 | // 转布尔值 108 | DART_EXPORT int32_t JSToBool(JSContext *ctx, JSValueConst *value); 109 | 110 | // 调用js方法 111 | DART_EXPORT JSValue *CallFuncton(JSContext *ctx, JSValueConst *func_obj, JSValueConst *this_obj, int32_t argc, JSValueConst *argv); 112 | 113 | // 调用构造函数 114 | DART_EXPORT JSValue *CallConstructor(JSContext *ctx, JSValueConst *func_obj, int argc, JSValueConst *argv); 115 | 116 | // 是否是数组 117 | DART_EXPORT int32_t IsArray(JSContext *ctx, JSValueConst *value); 118 | 119 | // 是否是函数 120 | DART_EXPORT int32_t IsFunction(JSContext *ctx, JSValueConst *value); 121 | 122 | // 是否是promise 123 | DART_EXPORT int32_t IsPromise(JSContext *ctx, JSValueConst *value); 124 | 125 | // 是否是构造函数 126 | DART_EXPORT int32_t IsConstructor(JSContext *ctx, JSValueConst *value); 127 | } 128 | -------------------------------------------------------------------------------- /cxx/quickjs/Changelog: -------------------------------------------------------------------------------- 1 | 2021-03-27: 2 | 3 | - faster Array.prototype.push and Array.prototype.unshift 4 | - added JS_UpdateStackTop() 5 | - fixed Windows console 6 | - misc bug fixes 7 | 8 | 2020-11-08: 9 | 10 | - improved function parameter initializers 11 | - added std.setenv(), std.unsetenv() and std.getenviron() 12 | - added JS_EvalThis() 13 | - misc bug fixes 14 | 15 | 2020-09-06: 16 | 17 | - added logical assignment operators 18 | - added IsHTMLDDA support 19 | - faster for-of loops 20 | - os.Worker now takes a module filename as parameter 21 | - qjsc: added -D option to compile dynamically loaded modules or workers 22 | - misc bug fixes 23 | 24 | 2020-07-05: 25 | 26 | - modified JS_GetPrototype() to return a live value 27 | - REPL: support unicode characters larger than 16 bits 28 | - added os.Worker 29 | - improved object serialization 30 | - added std.parseExtJSON 31 | - misc bug fixes 32 | 33 | 2020-04-12: 34 | 35 | - added cross realm support 36 | - added AggregateError and Promise.any 37 | - added env, uid and gid options in os.exec() 38 | - misc bug fixes 39 | 40 | 2020-03-16: 41 | 42 | - reworked error handling in std and os libraries: suppressed I/O 43 | exceptions in std FILE functions and return a positive errno value 44 | when it is explicit 45 | - output exception messages to stderr 46 | - added std.loadFile(), std.strerror(), std.FILE.prototype.tello() 47 | - added JS_GetRuntimeOpaque(), JS_SetRuntimeOpaque(), JS_NewUint32() 48 | - updated to Unicode 13.0.0 49 | - misc bug fixes 50 | 51 | 2020-01-19: 52 | 53 | - keep CONFIG_BIGNUM in the makefile 54 | - added os.chdir() 55 | - qjs: added -I option 56 | - more memory checks in the bignum operations 57 | - modified operator overloading semantics to be closer to the TC39 58 | proposal 59 | - suppressed "use bigint" mode. Simplified "use math" mode 60 | - BigDecimal: changed suffix from 'd' to 'm' 61 | - misc bug fixes 62 | 63 | 2020-01-05: 64 | 65 | - always compile the bignum code. Added '--bignum' option to qjs. 66 | - added BigDecimal 67 | - added String.prototype.replaceAll 68 | - misc bug fixes 69 | 70 | 2019-12-21: 71 | 72 | - added nullish coalescing operator (ES2020) 73 | - added optional chaining (ES2020) 74 | - removed recursions in garbage collector 75 | - test stack overflow in the parser 76 | - improved backtrace logic 77 | - added JS_SetHostPromiseRejectionTracker() 78 | - allow exotic constructors 79 | - improved c++ compatibility 80 | - misc bug fixes 81 | 82 | 2019-10-27: 83 | 84 | - added example of C class in a module (examples/test_point.js) 85 | - added JS_GetTypedArrayBuffer() 86 | - misc bug fixes 87 | 88 | 2019-09-18: 89 | 90 | - added os.exec and other system calls 91 | - exported JS_ValueToAtom() 92 | - qjsc: added 'qjsc_' prefix to the generated C identifiers 93 | - added cross-compilation support 94 | - misc bug fixes 95 | 96 | 2019-09-01: 97 | 98 | - added globalThis 99 | - documented JS_EVAL_FLAG_COMPILE_ONLY 100 | - added import.meta.url and import.meta.main 101 | - added 'debugger' statement 102 | - misc bug fixes 103 | 104 | 2019-08-18: 105 | 106 | - added os.realpath, os.getcwd, os.mkdir, os.stat, os.lstat, 107 | os.readlink, os.readdir, os.utimes, std.popen 108 | - module autodetection 109 | - added import.meta 110 | - misc bug fixes 111 | 112 | 2019-08-10: 113 | 114 | - added public class fields and private class fields, methods and 115 | accessors (TC39 proposal) 116 | - changed JS_ToCStringLen() prototype 117 | - qjsc: handle '-' in module names and modules with the same filename 118 | - added std.urlGet 119 | - exported JS_GetOwnPropertyNames() and JS_GetOwnProperty() 120 | - exported some bigint C functions 121 | - added support for eshost in run-test262 122 | - misc bug fixes 123 | 124 | 2019-07-28: 125 | 126 | - added dynamic import 127 | - added Promise.allSettled 128 | - added String.prototype.matchAll 129 | - added Object.fromEntries 130 | - reduced number of ticks in await 131 | - added BigInt support in Atomics 132 | - exported JS_NewPromiseCapability() 133 | - misc async function and async generator fixes 134 | - enabled hashbang support by default 135 | 136 | 2019-07-21: 137 | 138 | - updated test262 tests 139 | - updated to Unicode version 12.1.0 140 | - fixed missing Date object in qjsc 141 | - fixed multi-context creation 142 | - misc ES2020 related fixes 143 | - simplified power and division operators in bignum extension 144 | - fixed several crash conditions 145 | 146 | 2019-07-09: 147 | 148 | - first public release 149 | -------------------------------------------------------------------------------- /README-ZH.md: -------------------------------------------------------------------------------- 1 | # dart_quickjs 2 | 3 | [![Pub](https://img.shields.io/pub/v/dart_quickjs.svg)](https://pub.flutter-io.cn/packages/dart_quickjs) 4 | 5 | Language: 简体中文 | [English](README.md) 6 | 7 | ```dart_quickjs```是一个使用```Dart```对```QuickJS```引擎的一个绑定,支持在```Android``` ```IOS```中执行```JavaScript```代码, ```QuickJS``` 是一款轻量级, 并支持ECMAScript 2020规范的```JavaScript```引擎 8 | 9 | ## 开始使用 10 | 11 | ### 添加依赖 12 | ```console 13 | $ dart pub add dart_quickjs 14 | ``` 15 | 如果需要指定版本可以在```pubspec.yaml```文件中添加 16 | 17 | ```console 18 | dependencies: 19 | dart_quickjs: ^版本号 20 | ``` 21 | 最新稳定版本:![Pub](https://img.shields.io/pub/v/dart_quickjs.svg) 22 | 23 | ## 示例 24 | ```println```为```dart_quickjs```注入的打印函数 25 | ```dart 26 | import 'package:dart_quickjs/dart_quickjs.dart'; 27 | 28 | final runtime = Runtime(); 29 | const script = 'println("Hello World");'; 30 | 31 | runtime.evaluateJavaScript(script, 'main.js'); 32 | ``` 33 | 34 | ## 类型支持和映射 35 | | Dart | JavasCript | 36 | | - | - | 37 | | JSObject | Object | 38 | | JSString | String | 39 | | JSNumber | Number | 40 | | JSFloat | Number | 41 | | JSBool | Boolean | 42 | | JSArray | Array | 43 | | JSFunction | Function | 44 | | JSPromise | Promise | 45 | | JSNull | null | 46 | | JSUndefined | undefined | 47 | 48 | ## 注入对象 49 | ```dart 50 | import 'package:dart_quickjs/dart_quickjs.dart'; 51 | 52 | final runtime = Runtime(); 53 | // 创建和注入对象 54 | final value = JSString.create(runtime.context, 'dart_quickjs'); 55 | // 添加到全局对象 56 | runtime.global.setPropertyStr('name', value); 57 | // 打印name 58 | runtime.evaluateJavaScript('println(name);', 'main.js'); 59 | ``` 60 | 61 | ## 注入方法 62 | ```dart 63 | import 'package:dart_quickjs/dart_quickjs.dart'; 64 | 65 | final runtime = Runtime(); 66 | // 创建方法 67 | final value = JSFunction.create(runtime.context, (JSNumber data) { 68 | return JSNumber.create(runtime.context, data.value + 1); 69 | }); 70 | // 添加到全局对象 71 | runtime.global.setPropertyStr('add', value); 72 | // 执行代码 73 | runtime.evaluateJavaScript('println(add(1));', 'main.js'); 74 | ``` 75 | 76 | ## 通信 77 | ```JavaScript```调用```dart``` 78 | ```dart 79 | import 'package:dart_quickjs/dart_quickjs.dart'; 80 | 81 | final runtime = Runtime(); 82 | // 创建方法 83 | final value = JSFunction.create(runtime.context, (JSString message) { 84 | print('JavaScriptMessage: ${message.value}'); 85 | }); 86 | // 添加到全局对象 87 | runtime.global.setPropertyStr('test', value); 88 | // 执行代码 89 | runtime.evaluateJavaScript('test("dart_quickjs");', 'main.js'); 90 | ``` 91 | ```dart```调用```JavaScript``` 92 | ```dart 93 | import 'package:dart_quickjs/dart_quickjs.dart'; 94 | 95 | final runtime = Runtime(); 96 | // javascript代码 97 | const code = '''function message(value) { 98 | return value + 1; 99 | } 100 | message;'''; 101 | // 执行代码 102 | final callback = runtime.evaluateJavaScript(code, 'main.js') as JSFunction; 103 | // 调用javascript方法 104 | final value = callback.call([JSNumber.create(runtime.context, 1)]); 105 | // 打印返回值 106 | print(value); 107 | ``` 108 | 在通信中可以传递基础类型和函数类型 109 | ## module导入 110 | - 使用模块系统时需要传递```moduleLoader```方法来加载模块 111 | - 在运行入口时候运行模式需要设置成```JSEvalType.module``` 112 | 113 | ```dart 114 | import 'package:dart_quickjs/dart_quickjs.dart'; 115 | 116 | // 创建运行时 117 | final runtime = Runtime( 118 | moduleLoader: (String name) { 119 | if (name == 'message') { 120 | return "export const message = 'dart_quickjs'"; 121 | } 122 | 123 | return ''; 124 | }, 125 | ); 126 | // main.js 127 | const main = ''' 128 | import { message } from 'message' 129 | println(message) 130 | '''; 131 | // 执行代码 132 | runtime.evaluateJavaScript(main, 'main.js', JSEvalType.module); 133 | ``` 134 | 135 | ## 销毁和释放 136 | ```dart 137 | import 'package:dart_quickjs/dart_quickjs.dart'; 138 | 139 | final runtime = Runtime(); 140 | 141 | // 释放运行时 142 | runtime.destroy(); 143 | ``` 144 | 145 | ## 插件 146 | ```dart 147 | import 'package:dart_quickjs/dart_quickjs.dart'; 148 | 149 | class Test extends Plugin { 150 | late Runtime _runtime; 151 | 152 | @override 153 | void onCreate(Runtime runtime) { 154 | _runtime = runtime; 155 | // 注入方法 156 | runtime.global.setPropertyStr( 157 | 'getMessage', 158 | JSFunction.create(runtime.context, test), 159 | ); 160 | } 161 | 162 | JSString test(JSString data) { 163 | return JSString.create(_runtime.context, '${data.value} World'); 164 | } 165 | 166 | @override 167 | void destroy(Runtime runtime) {} 168 | } 169 | 170 | final runtime = Runtime( 171 | plugins: [ 172 | // 注册插件 173 | Test() 174 | ], 175 | ); 176 | 177 | const script = 'println(getMessage("Hello"));'; 178 | runtime.evaluateJavaScript(script, 'main.js'); 179 | ``` 180 | 181 | ## 字节码 182 | 183 | ```dart 184 | import 'package:dart_quickjs/dart_quickjs.dart'; 185 | 186 | final runtime = Runtime(); 187 | 188 | const script = 'println("Hello World");'; 189 | // 编译字节码 190 | final bytecode = runtime.compile(script, 'main.js'); 191 | // 运行字节码 192 | runtime.evaluateBytecode(bytecode); 193 | ``` 194 | 195 | ## 内置 javascript api方法 196 | ```println``` ```setInterval``` ```clearInterval``` ```setTimeout``` ```clearTimeout``` 197 | -------------------------------------------------------------------------------- /cxx/quickjs/test262.conf: -------------------------------------------------------------------------------- 1 | [config] 2 | # general settings for test262 ES6 version 3 | 4 | # framework style: old, new 5 | style=new 6 | 7 | # handle tests tagged as [noStrict]: yes, no, skip 8 | nostrict=yes 9 | 10 | # handle tests tagged as [strictOnly]: yes, no, skip 11 | strict=yes 12 | 13 | # test mode: default, default-nostrict, default-strict, strict, nostrict, both, all 14 | mode=default 15 | 16 | # handle tests flagged as [async]: yes, no, skip 17 | # for these, load 'harness/doneprintHandle.js' prior to test 18 | # and expect `print('Test262:AsyncTestComplete')` to be called for 19 | # successful termination 20 | async=yes 21 | 22 | # handle tests flagged as [module]: yes, no, skip 23 | module=yes 24 | 25 | # output error messages: yes, no 26 | verbose=yes 27 | 28 | # load harness files from this directory 29 | harnessdir=test262/harness 30 | 31 | # names of harness include files to skip 32 | #harnessexclude= 33 | 34 | # name of the error file for known errors 35 | errorfile=test262_errors.txt 36 | 37 | # exclude tests enumerated in this file (see also [exclude] section) 38 | #excludefile=test262_exclude.txt 39 | 40 | # report test results to this file 41 | reportfile=test262_report.txt 42 | 43 | # enumerate tests from this directory 44 | testdir=test262/test 45 | 46 | [features] 47 | # Standard language features and proposed extensions 48 | # list the features that are included 49 | # skipped features are tagged as such to avoid warnings 50 | 51 | AggregateError 52 | align-detached-buffer-semantics-with-web-reality 53 | arbitrary-module-namespace-names=skip 54 | Array.prototype.at=skip 55 | Array.prototype.flat 56 | Array.prototype.flatMap 57 | Array.prototype.flatten 58 | Array.prototype.values 59 | ArrayBuffer 60 | arrow-function 61 | async-functions 62 | async-iteration 63 | Atomics 64 | Atomics.waitAsync=skip 65 | BigInt 66 | caller 67 | class 68 | class-fields-private 69 | class-fields-public 70 | class-methods-private 71 | class-static-fields-public 72 | class-static-fields-private 73 | class-static-methods-private 74 | cleanupSome=skip 75 | coalesce-expression 76 | computed-property-names 77 | const 78 | cross-realm 79 | DataView 80 | DataView.prototype.getFloat32 81 | DataView.prototype.getFloat64 82 | DataView.prototype.getInt16 83 | DataView.prototype.getInt32 84 | DataView.prototype.getInt8 85 | DataView.prototype.getUint16 86 | DataView.prototype.getUint32 87 | DataView.prototype.setUint8 88 | default-parameters 89 | destructuring-assignment 90 | destructuring-binding 91 | dynamic-import 92 | export-star-as-namespace-from-module 93 | FinalizationGroup=skip 94 | FinalizationRegistry=skip 95 | FinalizationRegistry.prototype.cleanupSome=skip 96 | Float32Array 97 | Float64Array 98 | for-in-order 99 | for-of 100 | generators 101 | globalThis 102 | hashbang 103 | host-gc-required=skip 104 | import.meta 105 | Int16Array 106 | Int32Array 107 | Int8Array 108 | IsHTMLDDA 109 | json-superset 110 | legacy-regexp=skip 111 | let 112 | logical-assignment-operators 113 | Map 114 | new.target 115 | numeric-separator-literal 116 | object-rest 117 | object-spread 118 | Object.fromEntries 119 | Object.is 120 | optional-catch-binding 121 | optional-chaining 122 | Promise 123 | Promise.allSettled 124 | Promise.any 125 | Promise.prototype.finally 126 | Proxy 127 | proxy-missing-checks 128 | Reflect 129 | Reflect.construct 130 | Reflect.set 131 | Reflect.setPrototypeOf 132 | regexp-dotall 133 | regexp-lookbehind 134 | regexp-match-indices=skip 135 | regexp-named-groups 136 | regexp-unicode-property-escapes 137 | rest-parameters 138 | Set 139 | SharedArrayBuffer 140 | string-trimming 141 | String.fromCodePoint 142 | String.prototype.endsWith 143 | String.prototype.includes 144 | String.prototype.at=skip 145 | String.prototype.matchAll 146 | String.prototype.replaceAll 147 | String.prototype.trimEnd 148 | String.prototype.trimStart 149 | super 150 | Symbol 151 | Symbol.asyncIterator 152 | Symbol.hasInstance 153 | Symbol.isConcatSpreadable 154 | Symbol.iterator 155 | Symbol.match 156 | Symbol.matchAll 157 | Symbol.prototype.description 158 | Symbol.replace 159 | Symbol.search 160 | Symbol.species 161 | Symbol.split 162 | Symbol.toPrimitive 163 | Symbol.toStringTag 164 | Symbol.unscopables 165 | tail-call-optimization=skip 166 | template 167 | top-level-await=skip 168 | TypedArray 169 | TypedArray.prototype.at=skip 170 | u180e 171 | Uint16Array 172 | Uint32Array 173 | Uint8Array 174 | Uint8ClampedArray 175 | WeakMap 176 | WeakRef=skip 177 | WeakSet 178 | well-formed-json-stringify 179 | __getter__ 180 | __proto__ 181 | __setter__ 182 | 183 | [exclude] 184 | # list excluded tests and directories here 185 | 186 | # intl not supported 187 | test262/test/intl402/ 188 | 189 | # incompatible with the "caller" feature 190 | test262/test/built-ins/Function/prototype/restricted-property-caller.js 191 | test262/test/built-ins/Function/prototype/restricted-property-arguments.js 192 | test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js 193 | 194 | # slow tests 195 | #test262/test/built-ins/RegExp/CharacterClassEscapes/ 196 | #test262/test/built-ins/RegExp/property-escapes/ 197 | 198 | [tests] 199 | # list test files or use config.testdir 200 | -------------------------------------------------------------------------------- /cxx/quickjs/tests/test_closure.js: -------------------------------------------------------------------------------- 1 | function assert(actual, expected, message) { 2 | if (arguments.length == 1) 3 | expected = true; 4 | 5 | if (actual === expected) 6 | return; 7 | 8 | if (actual !== null && expected !== null 9 | && typeof actual == 'object' && typeof expected == 'object' 10 | && actual.toString() === expected.toString()) 11 | return; 12 | 13 | throw Error("assertion failed: got |" + actual + "|" + 14 | ", expected |" + expected + "|" + 15 | (message ? " (" + message + ")" : "")); 16 | } 17 | 18 | // load more elaborate version of assert if available 19 | try { __loadScript("test_assert.js"); } catch(e) {} 20 | 21 | /*----------------*/ 22 | 23 | var log_str = ""; 24 | 25 | function log(str) 26 | { 27 | log_str += str + ","; 28 | } 29 | 30 | function f(a, b, c) 31 | { 32 | var x = 10; 33 | log("a="+a); 34 | function g(d) { 35 | function h() { 36 | log("d=" + d); 37 | log("x=" + x); 38 | } 39 | log("b=" + b); 40 | log("c=" + c); 41 | h(); 42 | } 43 | g(4); 44 | return g; 45 | } 46 | 47 | var g1 = f(1, 2, 3); 48 | g1(5); 49 | 50 | assert(log_str, "a=1,b=2,c=3,d=4,x=10,b=2,c=3,d=5,x=10,", "closure1"); 51 | 52 | function test_closure1() 53 | { 54 | function f2() 55 | { 56 | var val = 1; 57 | 58 | function set(a) { 59 | val = a; 60 | } 61 | function get(a) { 62 | return val; 63 | } 64 | return { "set": set, "get": get }; 65 | } 66 | 67 | var obj = f2(); 68 | obj.set(10); 69 | var r; 70 | r = obj.get(); 71 | assert(r, 10, "closure2"); 72 | } 73 | 74 | function test_closure2() 75 | { 76 | var expr_func = function myfunc1(n) { 77 | function myfunc2(n) { 78 | return myfunc1(n - 1); 79 | } 80 | if (n == 0) 81 | return 0; 82 | else 83 | return myfunc2(n); 84 | }; 85 | var r; 86 | r = expr_func(1); 87 | assert(r, 0, "expr_func"); 88 | } 89 | 90 | function test_closure3() 91 | { 92 | function fib(n) 93 | { 94 | if (n <= 0) 95 | return 0; 96 | else if (n == 1) 97 | return 1; 98 | else 99 | return fib(n - 1) + fib(n - 2); 100 | } 101 | 102 | var fib_func = function fib1(n) 103 | { 104 | if (n <= 0) 105 | return 0; 106 | else if (n == 1) 107 | return 1; 108 | else 109 | return fib1(n - 1) + fib1(n - 2); 110 | }; 111 | 112 | assert(fib(6), 8, "fib"); 113 | assert(fib_func(6), 8, "fib_func"); 114 | } 115 | 116 | function test_arrow_function() 117 | { 118 | "use strict"; 119 | 120 | function f1() { 121 | return (() => arguments)(); 122 | } 123 | function f2() { 124 | return (() => this)(); 125 | } 126 | function f3() { 127 | return (() => eval("this"))(); 128 | } 129 | function f4() { 130 | return (() => eval("new.target"))(); 131 | } 132 | var a; 133 | 134 | a = f1(1, 2); 135 | assert(a.length, 2); 136 | assert(a[0] === 1 && a[1] === 2); 137 | 138 | assert(f2.call("this_val") === "this_val"); 139 | assert(f3.call("this_val") === "this_val"); 140 | assert(new f4() === f4); 141 | 142 | var o1 = { f() { return this; } }; 143 | var o2 = { f() { 144 | return (() => eval("super.f()"))(); 145 | } }; 146 | o2.__proto__ = o1; 147 | 148 | assert(o2.f() === o2); 149 | } 150 | 151 | function test_with() 152 | { 153 | var o1 = { x: "o1", y: "o1" }; 154 | var x = "local"; 155 | eval('var z="var_obj";'); 156 | assert(z === "var_obj"); 157 | with (o1) { 158 | assert(x === "o1"); 159 | assert(eval("x") === "o1"); 160 | var f = function () { 161 | o2 = { x: "o2" }; 162 | with (o2) { 163 | assert(x === "o2"); 164 | assert(y === "o1"); 165 | assert(z === "var_obj"); 166 | assert(eval("x") === "o2"); 167 | assert(eval("y") === "o1"); 168 | assert(eval("z") === "var_obj"); 169 | assert(eval('eval("x")') === "o2"); 170 | } 171 | }; 172 | f(); 173 | } 174 | } 175 | 176 | function test_eval_closure() 177 | { 178 | var tab; 179 | 180 | tab = []; 181 | for(let i = 0; i < 3; i++) { 182 | eval("tab.push(function g1() { return i; })"); 183 | } 184 | for(let i = 0; i < 3; i++) { 185 | assert(tab[i]() === i); 186 | } 187 | 188 | tab = []; 189 | for(let i = 0; i < 3; i++) { 190 | let f = function f() { 191 | eval("tab.push(function g2() { return i; })"); 192 | }; 193 | f(); 194 | } 195 | for(let i = 0; i < 3; i++) { 196 | assert(tab[i]() === i); 197 | } 198 | } 199 | 200 | function test_eval_const() 201 | { 202 | const a = 1; 203 | var success = false; 204 | var f = function () { 205 | eval("a = 1"); 206 | }; 207 | try { 208 | f(); 209 | } catch(e) { 210 | success = (e instanceof TypeError); 211 | } 212 | assert(success); 213 | } 214 | 215 | test_closure1(); 216 | test_closure2(); 217 | test_closure3(); 218 | test_arrow_function(); 219 | test_with(); 220 | test_eval_closure(); 221 | test_eval_const(); 222 | -------------------------------------------------------------------------------- /cxx/quickjs/examples/point.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module with a class 3 | * 4 | * Copyright (c) 2019 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | #include 26 | 27 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 28 | 29 | /* Point Class */ 30 | 31 | typedef struct { 32 | int x; 33 | int y; 34 | } JSPointData; 35 | 36 | static JSClassID js_point_class_id; 37 | 38 | static void js_point_finalizer(JSRuntime *rt, JSValue val) 39 | { 40 | JSPointData *s = JS_GetOpaque(val, js_point_class_id); 41 | /* Note: 's' can be NULL in case JS_SetOpaque() was not called */ 42 | js_free_rt(rt, s); 43 | } 44 | 45 | static JSValue js_point_ctor(JSContext *ctx, 46 | JSValueConst new_target, 47 | int argc, JSValueConst *argv) 48 | { 49 | JSPointData *s; 50 | JSValue obj = JS_UNDEFINED; 51 | JSValue proto; 52 | 53 | s = js_mallocz(ctx, sizeof(*s)); 54 | if (!s) 55 | return JS_EXCEPTION; 56 | if (JS_ToInt32(ctx, &s->x, argv[0])) 57 | goto fail; 58 | if (JS_ToInt32(ctx, &s->y, argv[1])) 59 | goto fail; 60 | /* using new_target to get the prototype is necessary when the 61 | class is extended. */ 62 | proto = JS_GetPropertyStr(ctx, new_target, "prototype"); 63 | if (JS_IsException(proto)) 64 | goto fail; 65 | obj = JS_NewObjectProtoClass(ctx, proto, js_point_class_id); 66 | JS_FreeValue(ctx, proto); 67 | if (JS_IsException(obj)) 68 | goto fail; 69 | JS_SetOpaque(obj, s); 70 | return obj; 71 | fail: 72 | js_free(ctx, s); 73 | JS_FreeValue(ctx, obj); 74 | return JS_EXCEPTION; 75 | } 76 | 77 | static JSValue js_point_get_xy(JSContext *ctx, JSValueConst this_val, int magic) 78 | { 79 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 80 | if (!s) 81 | return JS_EXCEPTION; 82 | if (magic == 0) 83 | return JS_NewInt32(ctx, s->x); 84 | else 85 | return JS_NewInt32(ctx, s->y); 86 | } 87 | 88 | static JSValue js_point_set_xy(JSContext *ctx, JSValueConst this_val, JSValue val, int magic) 89 | { 90 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 91 | int v; 92 | if (!s) 93 | return JS_EXCEPTION; 94 | if (JS_ToInt32(ctx, &v, val)) 95 | return JS_EXCEPTION; 96 | if (magic == 0) 97 | s->x = v; 98 | else 99 | s->y = v; 100 | return JS_UNDEFINED; 101 | } 102 | 103 | static JSValue js_point_norm(JSContext *ctx, JSValueConst this_val, 104 | int argc, JSValueConst *argv) 105 | { 106 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 107 | if (!s) 108 | return JS_EXCEPTION; 109 | return JS_NewFloat64(ctx, sqrt((double)s->x * s->x + (double)s->y * s->y)); 110 | } 111 | 112 | static JSClassDef js_point_class = { 113 | "Point", 114 | .finalizer = js_point_finalizer, 115 | }; 116 | 117 | static const JSCFunctionListEntry js_point_proto_funcs[] = { 118 | JS_CGETSET_MAGIC_DEF("x", js_point_get_xy, js_point_set_xy, 0), 119 | JS_CGETSET_MAGIC_DEF("y", js_point_get_xy, js_point_set_xy, 1), 120 | JS_CFUNC_DEF("norm", 0, js_point_norm), 121 | }; 122 | 123 | static int js_point_init(JSContext *ctx, JSModuleDef *m) 124 | { 125 | JSValue point_proto, point_class; 126 | 127 | /* create the Point class */ 128 | JS_NewClassID(&js_point_class_id); 129 | JS_NewClass(JS_GetRuntime(ctx), js_point_class_id, &js_point_class); 130 | 131 | point_proto = JS_NewObject(ctx); 132 | JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs)); 133 | 134 | point_class = JS_NewCFunction2(ctx, js_point_ctor, "Point", 2, JS_CFUNC_constructor, 0); 135 | /* set proto.constructor and ctor.prototype */ 136 | JS_SetConstructor(ctx, point_class, point_proto); 137 | JS_SetClassProto(ctx, js_point_class_id, point_proto); 138 | 139 | JS_SetModuleExport(ctx, m, "Point", point_class); 140 | return 0; 141 | } 142 | 143 | JSModuleDef *js_init_module(JSContext *ctx, const char *module_name) 144 | { 145 | JSModuleDef *m; 146 | m = JS_NewCModule(ctx, module_name, js_point_init); 147 | if (!m) 148 | return NULL; 149 | JS_AddModuleExport(ctx, m, "Point"); 150 | return m; 151 | } 152 | --------------------------------------------------------------------------------