Skip to content

Commit

Permalink
feat: add class basic support and bench action
Browse files Browse the repository at this point in the history
  • Loading branch information
XGHeaven committed Jun 8, 2024
1 parent dd6bfe7 commit 265f7d0
Show file tree
Hide file tree
Showing 12 changed files with 504 additions and 21 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/benchmark.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Benchmark
on:
workflow_dispatch:
# schedule:
# - corn: '0 4 * * *'
# push:
# branches:
# - main
jobs:
Test262:
runs-on: ubuntu-latest
environment: Benchmark
steps:
- name: Check out repository code
uses: actions/checkout@v4
with:
submodules: true

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
run_install: false

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install

- name: Build source
run: pnpm run build
continue-on-error: true

- name: Run benchmark
run: pnpm run bench
11 changes: 10 additions & 1 deletion benchmark/cases/v8-7/_build.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
const fs = require('fs')
const path = require('path')

const files = ['crypto', 'deltablue', 'earley-boyer', 'navier-stokes', 'raytrace', 'regexp', 'richards', 'splay']
const files = [
'crypto',
'deltablue',
// 'earley-boyer',
'navier-stokes',
// 'raytrace',
// 'regexp',
'richards',
'splay',
]

function read(file) {
return fs.readFileSync(path.join(__dirname, file), 'utf8')
Expand Down
10 changes: 10 additions & 0 deletions benchmark/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

set -e
node ./benchmark/cases/v8-7/_build.js

echo "Run jsscript"
./bin/jsscript run --browser ./benchmark/cases/v8-7/_bundle.js

echo "Run sablejs"
node ./benchmark/run-sable.js
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"test262:analysis": "node ./scripts/analysis.js",
"build": "tsc",
"fmt": "prettier -w './{src,scripts,benchmark}/**/*.{ts,js}'",
"fmt:check": "prettier -c './{src,scripts,benchmark}/**/*.{ts,js}'"
"fmt:check": "prettier -c './{src,scripts,benchmark}/**/*.{ts,js}'",
"bench": "bash ./benchmark/run.sh"
},
"files": [
"dist"
Expand Down
9 changes: 2 additions & 7 deletions src/builtin/Object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,19 @@ import {
JSDefinePropertyDesc,
JSGetOwnPropertyDescValue,
JSGetOwnPropertyKeys,
JSGetPrototype,
JSHasOwnProperty,
JSNewObjectFromCtor,
JSNewPlainObject,
JSObjectType,
isPrototypeOf,
jsFindOwnProperty,
makeObject,
} from '../object'
import {
JSObjectValue,
JSValueType,
JS_EXCEPTION,
JS_FALSE,
JS_NULL,
createBoolValue,
createStringValue,
isExceptionValue,
Expand Down Expand Up @@ -147,11 +146,7 @@ const objectGetOwnPropertyDescriptor: HostFunction = (ctx, _, args) => {
}

const objectGetPrototypeOf: HostFunction = (ctx, _, args) => {
const obj = JSToObject(ctx, args[0])
if (isExceptionValue(obj)) {
return obj
}
return obj.value.proto ? makeObject(obj.value.proto) : JS_NULL
return JSGetPrototype(ctx, args[0])
}

const objectGetOwnPropertyNames: HostFunction = (ctx, _, args) => {
Expand Down
86 changes: 85 additions & 1 deletion src/bytecode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export enum Bytecode {
PushConstId,
// () [] => [this]
PushThis,
PushNewTarget,
// (pc: number)
Goto,
// () [] => []
Expand All @@ -56,6 +57,8 @@ export enum Bytecode {
// () [v] => [v v]
Dup,

GetPrototypeOf,

// () [error] => []
Throw,
// (pos) [] => [throwContext]
Expand All @@ -72,6 +75,8 @@ export enum Bytecode {
// (fieldName: string) (obj v) => (obj)
DefineField,
DefineArrayElement,
DefineMethod,
DefineMethodComputed,
// (fieldName: string) (obj) => (obj v)
GetField,
// (fieldName: string) (obj) => (v)
Expand Down Expand Up @@ -112,6 +117,10 @@ export enum Bytecode {
ForOfStart,
ForIterNextOrGoto,

// Class
// (name) [parentClass] => [ctor, proto]
DefineClass,

// internal
Label,

Expand All @@ -126,9 +135,84 @@ export enum Bytecode {

export type Bytecodes = unknown[]

export interface BytecodeConfig<T extends unknown[] = []> {
interface BytecodeConfigs {
[Bytecode.Start]: BytecodeConfig<[]>
[Bytecode.Stop]: BytecodeConfig<[]>
[Bytecode.NumbericOp]: BytecodeConfig<[string]>
[Bytecode.EqEqEq]: BytecodeConfig<[]>
[Bytecode.EqEq]: BytecodeConfig<[]>
[Bytecode.Lt]: BytecodeConfig<[]>
[Bytecode.Gt]: BytecodeConfig<[]>
[Bytecode.Le]: BytecodeConfig<[]>
[Bytecode.Ge]: BytecodeConfig<[]>
[Bytecode.Not]: BytecodeConfig<[]>
[Bytecode.Neg]: BytecodeConfig<[]>
[Bytecode.ToNumber]: BytecodeConfig<[]>
[Bytecode.TypeOf]: BytecodeConfig<[]>
[Bytecode.BitNot]: BytecodeConfig<[]>
[Bytecode.PlusConst]: BytecodeConfig<[]>
[Bytecode.PlusConstId]: BytecodeConfig<[number]>
[Bytecode.PushConst]: BytecodeConfig<[any]>
[Bytecode.PushVoid]: BytecodeConfig<[]>
[Bytecode.PushConstId]: BytecodeConfig<[number]>
[Bytecode.PushThis]: BytecodeConfig<[]>
[Bytecode.Goto]: BytecodeConfig<[number]>
[Bytecode.Hoisted]: BytecodeConfig<[]>
[Bytecode.IfTrue]: BytecodeConfig<[number]>
[Bytecode.IfFalse]: BytecodeConfig<[number]>
[Bytecode.Call]: BytecodeConfig<[number]>
[Bytecode.CallMethod]: BytecodeConfig<[number]>
[Bytecode.CallConstructor]: BytecodeConfig<[number]>
[Bytecode.Apply]: BytecodeConfig<[]>
[Bytecode.Return]: BytecodeConfig<[]>
[Bytecode.Drop]: BytecodeConfig<[]>
[Bytecode.Dup]: BytecodeConfig<[]>
[Bytecode.Throw]: BytecodeConfig<[]>
[Bytecode.TryContext]: BytecodeConfig<[number]>
[Bytecode.NewFn]: BytecodeConfig<[fnId: number]>
[Bytecode.GetVar]: BytecodeConfig<[name: string]>
[Bytecode.SetVar]: BytecodeConfig<[string]>
[Bytecode.GetVarFromArg]: BytecodeConfig<[]>
[Bytecode.DefineField]: BytecodeConfig<[string]>
[Bytecode.DefineArrayElement]: BytecodeConfig<[]>
[Bytecode.GetField]: BytecodeConfig<[string]>
[Bytecode.GetFieldReplace]: BytecodeConfig<[string]>
[Bytecode.SetField]: BytecodeConfig<[string]>
[Bytecode.SetArrayElement]: BytecodeConfig<[]>
[Bytecode.GetAarryElement]: BytecodeConfig<[]>
[Bytecode.GetArrayElementReplace]: BytecodeConfig<[]>
[Bytecode.Delete]: BytecodeConfig<[]>
[Bytecode.InstanceOf]: BytecodeConfig<[]>
[Bytecode.In]: BytecodeConfig<[]>
[Bytecode.PushScope]: BytecodeConfig<[number]>
[Bytecode.PopScope]: BytecodeConfig<[]>
[Bytecode.Object]: BytecodeConfig<[]>
[Bytecode.Arguments]: BytecodeConfig<[]>
[Bytecode.RegExp]: BytecodeConfig<[string, string]>
[Bytecode.ArrayFrom]: BytecodeConfig<[number]>
[Bytecode.ArrayPush]: BytecodeConfig<[]>
[Bytecode.ForInStart]: BytecodeConfig<[]>
[Bytecode.ForOfStart]: BytecodeConfig<[]>
[Bytecode.ForIterNextOrGoto]: BytecodeConfig<[]>
[Bytecode.DefineClass]: BytecodeConfig<[className: string, fnId: number, flags: number]>
[Bytecode.Label]: BytecodeConfig<[]>
[Bytecode.Swap]: BytecodeConfig<[]>
[Bytecode.Warning]: BytecodeConfig<[string]>
[Bytecode.LastMark]: BytecodeConfig<[]>
[Bytecode.PushNewTarget]: BytecodeConfig<[]>
[Bytecode.GetPrototypeOf]: BytecodeConfig<[], [obj: object], [proto: object]>
[Bytecode.DefineMethod]: BytecodeConfig<[name: string, flags: number], [fn: Function], []>
[Bytecode.DefineMethodComputed]: BytecodeConfig<[flags: number], [fn: Function, name: string], []>
}

export type GetBytecodeConfig<T extends Bytecode> = BytecodeConfigs[T]
export type ForBytecodeArgs<T extends Bytecode> = GetBytecodeConfig<T>['args']

export interface BytecodeConfig<T extends unknown[] = [], VF extends unknown[] = [], VT extends unknown[] = []> {
args: T
size: T['length']
valueFrom: VF
valueTo: VT
}

function OP<Args extends unknown[], O extends Bytecode>(op: O): O & BytecodeConfig<Args> {
Expand Down
6 changes: 6 additions & 0 deletions src/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const JS_CLASS_FLAG_HAS_HERITAGE = 1 << 0
export const JS_CLASS_FLAG_HAS_CONSTRUCTOR = 1 << 1

export const JS_DEFINE_METHOD_NORMAL = 1 << (0 + 0)
export const JS_DEFINE_METHOD_GET = 1 << (0 + 1)
export const JS_DEFINE_METHOD_SET = 1 << (0 + 2)
Loading

0 comments on commit 265f7d0

Please sign in to comment.